ExternalStream.st
changeset 25136 1665620b0c7d
parent 25134 9eac80392554
child 25142 bd49177015de
equal deleted inserted replaced
25135:98f799af1e48 25136:1665620b0c7d
  2267 
  2267 
  2268 %{
  2268 %{
  2269     OBJ _handle  = __INST(handle);
  2269     OBJ _handle  = __INST(handle);
  2270 
  2270 
  2271     if (_handle != nil) {
  2271     if (_handle != nil) {
  2272 	if ((__INST(handleType) == @symbol(fileHandle))
  2272         if ((__INST(handleType) == @symbol(fileHandle))
  2273 	 || (__INST(handleType) == @symbol(socketHandle))) {
  2273          || (__INST(handleType) == @symbol(socketHandle))) {
  2274 	    RETURN (_handle);
  2274             RETURN (_handle);
  2275 	}
  2275         }
  2276 	if (__INST(handleType) == @symbol(pipeFilePointer)) {
  2276         if (__INST(handleType) == @symbol(pipeFilePointer)) {
  2277 	    RETURN (__MKINT(fileno(__FILEVal(_handle))));
  2277             RETURN (__MKINT(fileno(__FILEVal(_handle))));
  2278 	}
  2278         }
  2279 	if ((__INST(handleType) == nil)
  2279         if ((__INST(handleType) == nil)
  2280 	 || (__INST(handleType) == @symbol(filePointer))
  2280          || (__INST(handleType) == @symbol(filePointer))
  2281 	 || (__INST(handleType) == @symbol(socketFilePointer))
  2281          || (__INST(handleType) == @symbol(socketFilePointer))
  2282 	 || (__INST(handleType) == @symbol(pipeFilePointer))) {
  2282          || (__INST(handleType) == @symbol(pipeFilePointer))) {
       
  2283             FILE *file = __FILEVal(_handle);
       
  2284             if (file != NULL) {
       
  2285                 int fileNo = fileno(file);
       
  2286                 if (fileNo >= 0) {
  2283 #ifdef __win32__
  2287 #ifdef __win32__
  2284 	    RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileno(__FILEVal(_handle)))));
  2288                     RETURN(__MKEXTERNALADDRESS(_get_osfhandle(fileNo)));
  2285 #else
  2289 #else
  2286 	    FILE *file = __FILEVal(_handle);
  2290                     RETURN (__MKINT(fileNo));
  2287 	    if (file != NULL) {
       
  2288 		int fileNo = fileno(file);
       
  2289 		if (fileNo >= 0) {
       
  2290 		    RETURN (__MKINT(fileNo));
       
  2291 		}
       
  2292 	    }
       
  2293 #endif
  2291 #endif
  2294 	}
  2292                 }
       
  2293             }
       
  2294         }
  2295     }
  2295     }
  2296 %}.
  2296 %}.
  2297     ^ handle
  2297     ^ handle
  2298 
  2298 
  2299     "Modified: / 07-04-2017 / 16:34:40 / cg"
  2299     "Modified: / 07-04-2017 / 16:34:40 / cg"
  2442 ! !
  2442 ! !
  2443 
  2443 
  2444 !ExternalStream methodsFor:'defaults'!
  2444 !ExternalStream methodsFor:'defaults'!
  2445 
  2445 
  2446 bufferSizeForBulkCopy
  2446 bufferSizeForBulkCopy
  2447     "return the size of buffer used when copying big files/bulk data 
  2447     "return the size of buffer used when copying big files/bulk data
  2448      from one stream to another.
  2448      from one stream to another.
  2449      Due to a bug on older Windows systems, the default used
  2449      Due to a bug on older Windows systems, the default used
  2450      is chosen very conservatively, as the copy used to fail with big buffers.
  2450      is chosen very conservatively, as the copy used to fail with big buffers.
  2451      However, modern Windows systems seem to not suffer from that bug,
  2451      However, modern Windows systems seem to not suffer from that bug,
  2452      and bigger buffer sizes will dramatically increase the performance of
  2452      and bigger buffer sizes will dramatically increase the performance of
  2456      When nil, a somewhat conservative compromise is used."
  2456      When nil, a somewhat conservative compromise is used."
  2457 
  2457 
  2458     DefaultCopyBufferSize notNil ifTrue:[^ DefaultCopyBufferSize].
  2458     DefaultCopyBufferSize notNil ifTrue:[^ DefaultCopyBufferSize].
  2459 
  2459 
  2460     (OperatingSystem isMSWINDOWSlike and:[OperatingSystem isWin7Like not]) ifTrue:[
  2460     (OperatingSystem isMSWINDOWSlike and:[OperatingSystem isWin7Like not]) ifTrue:[
  2461         "/ mhmh - NT hangs, when copying bigger blocks to a network drive - why ?
  2461 	"/ mhmh - NT hangs, when copying bigger blocks to a network drive - why ?
  2462         ^ 1 * 1024.
  2462 	^ 1 * 1024.
  2463     ].
  2463     ].
  2464     ^ 64 * 1024.
  2464     ^ 64 * 1024.
  2465 
  2465 
  2466     "Created: / 13-03-2019 / 16:49:17 / Stefan Vogel"
  2466     "Created: / 13-03-2019 / 16:49:17 / Stefan Vogel"
  2467     "Modified: / 13-03-2019 / 23:19:43 / Stefan Vogel"
  2467     "Modified: / 13-03-2019 / 23:19:43 / Stefan Vogel"
  2513     "{ Pragma: +optSpace }"
  2513     "{ Pragma: +optSpace }"
  2514 
  2514 
  2515     "report an error, that the stream is in binary mode"
  2515     "report an error, that the stream is in binary mode"
  2516 
  2516 
  2517     ^ InvalidModeError
  2517     ^ InvalidModeError
  2518         raiseRequestWith:self
  2518 	raiseRequestWith:self
  2519         errorString:(self className , ' is in binary mode')
  2519 	errorString:(self className , ' is in binary mode')
  2520         "/ in:thisContext sender
  2520 	"/ in:thisContext sender
  2521 
  2521 
  2522     "Modified: / 08-05-1999 / 20:12:43 / cg"
  2522     "Modified: / 08-05-1999 / 20:12:43 / cg"
  2523     "Modified: / 28-06-2019 / 08:43:06 / Claus Gittinger"
  2523     "Modified: / 28-06-2019 / 08:43:06 / Claus Gittinger"
  2524 !
  2524 !
  2525 
  2525 
  2527     "{ Pragma: +optSpace }"
  2527     "{ Pragma: +optSpace }"
  2528 
  2528 
  2529     "report an error, that the stream is not in binary mode"
  2529     "report an error, that the stream is not in binary mode"
  2530 
  2530 
  2531     ^ InvalidModeError
  2531     ^ InvalidModeError
  2532         raiseRequestWith:self
  2532 	raiseRequestWith:self
  2533         errorString:(self className , ' is not in binary mode')
  2533 	errorString:(self className , ' is not in binary mode')
  2534         "/ in:thisContext sender
  2534 	"/ in:thisContext sender
  2535 
  2535 
  2536     "Modified: / 08-05-1999 / 20:12:40 / cg"
  2536     "Modified: / 08-05-1999 / 20:12:40 / cg"
  2537     "Modified: / 28-06-2019 / 08:43:11 / Claus Gittinger"
  2537     "Modified: / 28-06-2019 / 08:43:11 / Claus Gittinger"
  2538 !
  2538 !
  2539 
  2539 
  2541     "{ Pragma: +optSpace }"
  2541     "{ Pragma: +optSpace }"
  2542 
  2542 
  2543     "report an error, that the stream is not in buffered mode"
  2543     "report an error, that the stream is not in buffered mode"
  2544 
  2544 
  2545     ^ StreamError
  2545     ^ StreamError
  2546         raiseRequestWith:self
  2546 	raiseRequestWith:self
  2547         errorString:(self className , ' is unbuffered - operation not allowed')
  2547 	errorString:(self className , ' is unbuffered - operation not allowed')
  2548         "/ in:thisContext sender
  2548 	"/ in:thisContext sender
  2549 
  2549 
  2550     "Modified: / 08-05-1999 / 20:12:36 / cg"
  2550     "Modified: / 08-05-1999 / 20:12:36 / cg"
  2551     "Modified: / 28-06-2019 / 08:43:14 / Claus Gittinger"
  2551     "Modified: / 28-06-2019 / 08:43:14 / Claus Gittinger"
  2552 !
  2552 !
  2553 
  2553 
  2781      so it's possible to read alien (i.e. ms-dos) text as well.
  2781      so it's possible to read alien (i.e. ms-dos) text as well.
  2782      The line must be shorter than 32K characters - otherwise an error is signalled."
  2782      The line must be shorter than 32K characters - otherwise an error is signalled."
  2783 
  2783 
  2784     |line error|
  2784     |line error|
  2785 
  2785 
  2786 %{  /* STACK:100000 */
  2786 %{  /* STACK:50000 */
  2787 
  2787 
  2788     FILEPOINTER f;
  2788     FILEPOINTER f;
  2789     int len, ret;
  2789     int len, ret;
  2790     char buffer[32*1024];
  2790     char buffer[32*1024];
  2791     char *rslt, *nextPtr, *limit;
  2791     char *rslt, *nextPtr, *limit;
  3683     |buffer n|
  3683     |buffer n|
  3684 
  3684 
  3685     buffer := ByteArray uninitializedNew:count.
  3685     buffer := ByteArray uninitializedNew:count.
  3686     n := self nextAvailableBytes:count into:buffer startingAt:1.
  3686     n := self nextAvailableBytes:count into:buffer startingAt:1.
  3687     n == 0 ifTrue:[
  3687     n == 0 ifTrue:[
  3688         ^ #[]
  3688 	^ #[]
  3689     ].
  3689     ].
  3690 
  3690 
  3691     n ~~ count ifTrue:[
  3691     n ~~ count ifTrue:[
  3692         ^ buffer copyTo:n
  3692 	^ buffer copyTo:n
  3693     ].
  3693     ].
  3694     ^ buffer.
  3694     ^ buffer.
  3695 
  3695 
  3696     "
  3696     "
  3697      (ReadStream on:#(1 2 3 4 5)) nextAvailable:3
  3697      (ReadStream on:#(1 2 3 4 5)) nextAvailable:3
  3739     if ((__INST(handleType) == nil)
  3739     if ((__INST(handleType) == nil)
  3740      || (__INST(handleType) == @symbol(filePointer))
  3740      || (__INST(handleType) == @symbol(filePointer))
  3741      || (__INST(handleType) == @symbol(socketFilePointer))
  3741      || (__INST(handleType) == @symbol(socketFilePointer))
  3742      || (__INST(handleType) == @symbol(socketHandle))
  3742      || (__INST(handleType) == @symbol(socketHandle))
  3743      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3743      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3744         if (((fp = __INST(handle)) != nil)
  3744 	if (((fp = __INST(handle)) != nil)
  3745             && (__INST(mode) != @symbol(writeonly))
  3745 	    && (__INST(mode) != @symbol(writeonly))
  3746             && __bothSmallInteger(count, start)
  3746 	    && __bothSmallInteger(count, start)
  3747         ) {
  3747 	) {
  3748             f = __FILEVal(fp);
  3748 	    f = __FILEVal(fp);
  3749 
  3749 
  3750             cnt = __intVal(count);
  3750 	    cnt = __intVal(count);
  3751             offs = __intVal(start) - 1;
  3751 	    offs = __intVal(start) - 1;
  3752 
  3752 
  3753             if (__isExternalBytesLike(anObject)) {
  3753 	    if (__isExternalBytesLike(anObject)) {
  3754                 OBJ sz;
  3754 		OBJ sz;
  3755 
  3755 
  3756                 nInstBytes = 0;
  3756 		nInstBytes = 0;
  3757                 extPtr = (char *)(__externalBytesAddress(anObject));
  3757 		extPtr = (char *)(__externalBytesAddress(anObject));
  3758                 if (extPtr == NULL) goto bad;
  3758 		if (extPtr == NULL) goto bad;
  3759                 sz = __externalBytesSize(anObject);
  3759 		sz = __externalBytesSize(anObject);
  3760                 if (__isSmallInteger(sz)) {
  3760 		if (__isSmallInteger(sz)) {
  3761                     objSize = __intVal(sz);
  3761 		    objSize = __intVal(sz);
  3762                 } else {
  3762 		} else {
  3763                     objSize = 0; /* unknown */
  3763 		    objSize = 0; /* unknown */
  3764                 }
  3764 		}
  3765             } else {
  3765 	    } else {
  3766                 OBJ oClass = __Class(anObject);
  3766 		OBJ oClass = __Class(anObject);
  3767                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3767 		int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3768 
  3768 
  3769                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3769 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3770 
  3770 
  3771                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3771 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3772                     case BYTEARRAY:
  3772 		    case BYTEARRAY:
  3773                     case WORDARRAY:
  3773 		    case WORDARRAY:
  3774                     case LONGARRAY:
  3774 		    case LONGARRAY:
  3775                     case SWORDARRAY:
  3775 		    case SWORDARRAY:
  3776                     case SLONGARRAY:
  3776 		    case SLONGARRAY:
  3777                     case FLOATARRAY:
  3777 		    case FLOATARRAY:
  3778                         break;
  3778 			break;
  3779                     case DOUBLEARRAY:
  3779 		    case DOUBLEARRAY:
  3780 #ifdef __NEED_DOUBLE_ALIGN
  3780 #ifdef __NEED_DOUBLE_ALIGN
  3781                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3781 			nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3782 #endif
  3782 #endif
  3783                         break;
  3783 			break;
  3784                     case LONGLONGARRAY:
  3784 		    case LONGLONGARRAY:
  3785                     case SLONGLONGARRAY:
  3785 		    case SLONGLONGARRAY:
  3786 #ifdef __NEED_LONGLONG_ALIGN
  3786 #ifdef __NEED_LONGLONG_ALIGN
  3787                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3787 			nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3788 #endif
  3788 #endif
  3789                         break;
  3789 			break;
  3790                     default:
  3790 		    default:
  3791                         goto bad;
  3791 			goto bad;
  3792                 }
  3792 		}
  3793                 extPtr = (char *)0;
  3793 		extPtr = (char *)0;
  3794                 objSize = __Size(anObject) - nInstBytes;
  3794 		objSize = __Size(anObject) - nInstBytes;
  3795             }
  3795 	    }
  3796 
  3796 
  3797             if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3797 	    if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3798                 _buffered = (__INST(buffered) == true);
  3798 		_buffered = (__INST(buffered) == true);
  3799                 if (_buffered) {
  3799 		if (_buffered) {
  3800                     __READING__(f);
  3800 		    __READING__(f);
  3801                 }
  3801 		}
  3802 
  3802 
  3803                 if (extPtr) {
  3803 		if (extPtr) {
  3804                     __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3804 		    __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3805                 } else {
  3805 		} else {
  3806                     /*
  3806 		    /*
  3807                      * on interrupt, anObject may be moved to another location.
  3807 		     * on interrupt, anObject may be moved to another location.
  3808                      * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3808 		     * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3809                      * to get a new address.
  3809 		     * to get a new address.
  3810                      */
  3810 		     */
  3811                     offs += nInstBytes;
  3811 		    offs += nInstBytes;
  3812                     __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3812 		    __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3813                 }
  3813 		}
  3814                 /* 0 is NOT an EOF condition here ... */
  3814 		/* 0 is NOT an EOF condition here ... */
  3815                 if (ret >= 0) {
  3815 		if (ret >= 0) {
  3816                     if (__isSmallInteger(__INST(position))) {
  3816 		    if (__isSmallInteger(__INST(position))) {
  3817                         INT np = __intVal(__INST(position)) + ret;
  3817 			INT np = __intVal(__INST(position)) + ret;
  3818                         OBJ t;
  3818 			OBJ t;
  3819 
  3819 
  3820                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3820 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3821                     } else {
  3821 		    } else {
  3822                         __INST(position) = nil; /* i.e. do not know */
  3822 			__INST(position) = nil; /* i.e. do not know */
  3823                     }
  3823 		    }
  3824                     RETURN (__mkSmallInteger(ret));
  3824 		    RETURN (__mkSmallInteger(ret));
  3825                 }
  3825 		}
  3826                 __INST(position) = nil;
  3826 		__INST(position) = nil;
  3827 # ifdef __win32__
  3827 # ifdef __win32__
  3828                 __threadErrno = __WIN32_ERR(GetLastError());
  3828 		__threadErrno = __WIN32_ERR(GetLastError());
  3829 # endif
  3829 # endif
  3830                 error = __mkSmallInteger(__threadErrno);
  3830 		error = __mkSmallInteger(__threadErrno);
  3831             }
  3831 	    }
  3832         }
  3832 	}
  3833     }
  3833     }
  3834 bad: ;
  3834 bad: ;
  3835 %}.
  3835 %}.
  3836     hitEOF ifTrue:[^ 0].
  3836     hitEOF ifTrue:[^ 0].
  3837     error notNil ifTrue:[
  3837     error notNil ifTrue:[
  3838         lastErrorNumber := error.
  3838 	lastErrorNumber := error.
  3839         ^ self readError:error
  3839 	^ self readError:error
  3840     ].
  3840     ].
  3841     handle isNil ifTrue:[^ self errorNotOpen].
  3841     handle isNil ifTrue:[^ self errorNotOpen].
  3842     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  3842     (mode == #writeonly) ifTrue:[^ self errorWriteOnly].
  3843     "
  3843     "
  3844      count not integer or arg not bit-like (String, ByteArray etc)
  3844      count not integer or arg not bit-like (String, ByteArray etc)
  4618 
  4618 
  4619     |error|
  4619     |error|
  4620 %{
  4620 %{
  4621     int num;
  4621     int num;
  4622     union {
  4622     union {
  4623         char bytes[2];
  4623 	char bytes[2];
  4624         short shortVal;
  4624 	short shortVal;
  4625     } u;
  4625     } u;
  4626     OBJ fp;
  4626     OBJ fp;
  4627 
  4627 
  4628     __INST(lastErrorNumber) = nil;
  4628     __INST(lastErrorNumber) = nil;
  4629     if ((__INST(handleType) == nil)
  4629     if ((__INST(handleType) == nil)
  4630      || (__INST(handleType) == @symbol(filePointer))
  4630      || (__INST(handleType) == @symbol(filePointer))
  4631      || (__INST(handleType) == @symbol(socketFilePointer))
  4631      || (__INST(handleType) == @symbol(socketFilePointer))
  4632      || (__INST(handleType) == @symbol(socketHandle))
  4632      || (__INST(handleType) == @symbol(socketHandle))
  4633      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4633      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4634         if (((fp = __INST(handle)) != nil)
  4634 	if (((fp = __INST(handle)) != nil)
  4635          && (__INST(mode) != @symbol(readonly))
  4635 	 && (__INST(mode) != @symbol(readonly))
  4636         ) {
  4636 	) {
  4637             FILEPOINTER f = __FILEVal(fp);
  4637 	    FILEPOINTER f = __FILEVal(fp);
  4638             int _buffered = (__INST(buffered) == true);
  4638 	    int _buffered = (__INST(buffered) == true);
  4639             int cnt;
  4639 	    int cnt;
  4640 
  4640 
  4641             if (__isSmallInteger(anIntegerOrCharacter)) {
  4641 	    if (__isSmallInteger(anIntegerOrCharacter)) {
  4642                 num = __intVal(anIntegerOrCharacter);
  4642 		num = __intVal(anIntegerOrCharacter);
  4643             } else if (__isCharacter(anIntegerOrCharacter)) {
  4643 	    } else if (__isCharacter(anIntegerOrCharacter)) {
  4644                 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4644 		num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4645             } else
  4645 	    } else
  4646                 goto out;
  4646 		goto out;
  4647 
  4647 
  4648             u.shortVal = num;
  4648 	    u.shortVal = num;
  4649 
  4649 
  4650             if (_buffered) {
  4650 	    if (_buffered) {
  4651                 __WRITING__(f)
  4651 		__WRITING__(f)
  4652             }
  4652 	    }
  4653             __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4653 	    __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4654 
  4654 
  4655             if (cnt == 2) {
  4655 	    if (cnt == 2) {
  4656                 if (__isSmallInteger(__INST(position))) {
  4656 		if (__isSmallInteger(__INST(position))) {
  4657                     INT np = __intVal(__INST(position)) + 2;
  4657 		    INT np = __intVal(__INST(position)) + 2;
  4658                     OBJ t;
  4658 		    OBJ t;
  4659 
  4659 
  4660                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4660 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4661                 } else {
  4661 		} else {
  4662                     __INST(position) = nil; /* i.e. do not know */
  4662 		    __INST(position) = nil; /* i.e. do not know */
  4663                 }
  4663 		}
  4664                 RETURN ( self );
  4664 		RETURN ( self );
  4665             }
  4665 	    }
  4666             __INST(position) = nil; /* i.e. do not know */
  4666 	    __INST(position) = nil; /* i.e. do not know */
  4667 # ifdef __win32__
  4667 # ifdef __win32__
  4668             __threadErrno = __WIN32_ERR(GetLastError());
  4668 	    __threadErrno = __WIN32_ERR(GetLastError());
  4669 # endif
  4669 # endif
  4670             error = __mkSmallInteger(__threadErrno);
  4670 	    error = __mkSmallInteger(__threadErrno);
  4671         }
  4671 	}
  4672     }
  4672     }
  4673 out:;
  4673 out:;
  4674 %}.
  4674 %}.
  4675     self nextPutInt16:anIntegerOrCharacter MSB:(UninterpretedBytes isBigEndian).
  4675     self nextPutInt16:anIntegerOrCharacter MSB:(UninterpretedBytes isBigEndian).
  4676 
  4676 
  4811      This is the CPU-specific byte order (LSB on x86 and VAX, MSB on sparc and possibly on ARM).
  4811      This is the CPU-specific byte order (LSB on x86 and VAX, MSB on sparc and possibly on ARM).
  4812      Notice that integers in the range 16r-80000000 to +16rFFFFFFFF can be written
  4812      Notice that integers in the range 16r-80000000 to +16rFFFFFFFF can be written
  4813      (i.e. both signed and unsigned int32 values can be written.
  4813      (i.e. both signed and unsigned int32 values can be written.
  4814      Works in both binary and text modes.
  4814      Works in both binary and text modes.
  4815      Notice: this message should not be sent explicitly by ANY program.
  4815      Notice: this message should not be sent explicitly by ANY program.
  4816              the following implementation replaces the code of either nextPutInt32MSB or LSB
  4816 	     the following implementation replaces the code of either nextPutInt32MSB or LSB
  4817              dynamically (see #initialize on the class side)"
  4817 	     dynamically (see #initialize on the class side)"
  4818 
  4818 
  4819     |error|
  4819     |error|
  4820 
  4820 
  4821 %{
  4821 %{
  4822     int num;
  4822     int num;
  4823     union {
  4823     union {
  4824         char bytes[4];
  4824 	char bytes[4];
  4825         int intVal;
  4825 	int intVal;
  4826     } u;
  4826     } u;
  4827     OBJ fp;
  4827     OBJ fp;
  4828 
  4828 
  4829     __INST(lastErrorNumber) = nil;
  4829     __INST(lastErrorNumber) = nil;
  4830     if (__isSmallInteger(anInteger)) {
  4830     if (__isSmallInteger(anInteger)) {
  4831         num = __intVal(anInteger);
  4831 	num = __intVal(anInteger);
  4832     } else {
  4832     } else {
  4833 #if __POINTER_SIZE__ == 8
  4833 #if __POINTER_SIZE__ == 8
  4834         // always more than 4-bytes
  4834 	// always more than 4-bytes
  4835         goto badArg;
  4835 	goto badArg;
  4836 #else
  4836 #else
  4837         num = __longIntVal(anInteger);
  4837 	num = __longIntVal(anInteger);
  4838         if (num == 0) {
  4838 	if (num == 0) {
  4839             num = __signedLongIntVal(anInteger);
  4839 	    num = __signedLongIntVal(anInteger);
  4840             if (num == 0) {
  4840 	    if (num == 0) {
  4841                 /* bad arg or out-of-range integer
  4841 		/* bad arg or out-of-range integer
  4842                  * (handled by the fallBack code)
  4842 		 * (handled by the fallBack code)
  4843                  */
  4843 		 */
  4844                 goto badArg;
  4844 		goto badArg;
  4845             }
  4845 	    }
  4846         }
  4846 	}
  4847 #endif
  4847 #endif
  4848     }
  4848     }
  4849 
  4849 
  4850     if ((__INST(handleType) == nil)
  4850     if ((__INST(handleType) == nil)
  4851      || (__INST(handleType) == @symbol(filePointer))
  4851      || (__INST(handleType) == @symbol(filePointer))
  4852      || (__INST(handleType) == @symbol(socketFilePointer))
  4852      || (__INST(handleType) == @symbol(socketFilePointer))
  4853      || (__INST(handleType) == @symbol(socketHandle))
  4853      || (__INST(handleType) == @symbol(socketHandle))
  4854      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4854      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4855         if (((fp = __INST(handle)) != nil)
  4855 	if (((fp = __INST(handle)) != nil)
  4856          && (__INST(mode) != @symbol(readonly))
  4856 	 && (__INST(mode) != @symbol(readonly))
  4857         ) {
  4857 	) {
  4858             int _buffered = (__INST(buffered) == true);
  4858 	    int _buffered = (__INST(buffered) == true);
  4859             FILEPOINTER f = __FILEVal(fp);
  4859 	    FILEPOINTER f = __FILEVal(fp);
  4860             int cnt;
  4860 	    int cnt;
  4861 
  4861 
  4862             u.intVal = num;
  4862 	    u.intVal = num;
  4863             if (_buffered) {
  4863 	    if (_buffered) {
  4864                 __WRITING__(f)
  4864 		__WRITING__(f)
  4865             }
  4865 	    }
  4866             __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
  4866 	    __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
  4867 
  4867 
  4868             if (cnt == 4) {
  4868 	    if (cnt == 4) {
  4869                 if (__isSmallInteger(__INST(position))) {
  4869 		if (__isSmallInteger(__INST(position))) {
  4870                     INT np = __intVal(__INST(position)) + 4;
  4870 		    INT np = __intVal(__INST(position)) + 4;
  4871                     OBJ t;
  4871 		    OBJ t;
  4872 
  4872 
  4873                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4873 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4874                 } else {
  4874 		} else {
  4875                     __INST(position) = nil; /* i.e. do not know */
  4875 		    __INST(position) = nil; /* i.e. do not know */
  4876                 }
  4876 		}
  4877                 RETURN ( self );
  4877 		RETURN ( self );
  4878             }
  4878 	    }
  4879             __INST(position) = nil; /* i.e. do not know */
  4879 	    __INST(position) = nil; /* i.e. do not know */
  4880 # ifdef __win32__
  4880 # ifdef __win32__
  4881             __threadErrno = __WIN32_ERR(GetLastError());
  4881 	    __threadErrno = __WIN32_ERR(GetLastError());
  4882 # endif
  4882 # endif
  4883             error = __mkSmallInteger(__threadErrno);
  4883 	    error = __mkSmallInteger(__threadErrno);
  4884         }
  4884 	}
  4885     }
  4885     }
  4886 badArg: ;
  4886 badArg: ;
  4887 %}.
  4887 %}.
  4888     self nextPutInt32:anInteger MSB:(UninterpretedBytes isBigEndian)
  4888     self nextPutInt32:anInteger MSB:(UninterpretedBytes isBigEndian)
  4889 
  4889 
  6167         ^ self errorNotOpen
  6167         ^ self errorNotOpen
  6168     ].
  6168     ].
  6169     mode == #readonly ifTrue:[
  6169     mode == #readonly ifTrue:[
  6170         ^ self errorReadOnly
  6170         ^ self errorReadOnly
  6171     ].
  6171     ].
       
  6172 %{
       
  6173 #ifdef __win32__
       
  6174     {
       
  6175         FILEPOINTER f = __FILEVal(__INST(handle));
       
  6176         if ((f == __win32_stdout()) || (f == __win32_stderr())) {
       
  6177             RETURN(false);
       
  6178         }
       
  6179     }
       
  6180 #endif
       
  6181 %}.
  6172 
  6182 
  6173     fd := self fileHandle.
  6183     fd := self fileHandle.
  6174     (OperatingSystem writeCheck:fd) ifTrue:[^ false].
  6184     (OperatingSystem writeCheck:fd) ifTrue:[^ false].
  6175 
  6185 
  6176     wasBlocked := OperatingSystem blockInterrupts.
  6186     wasBlocked := OperatingSystem blockInterrupts.
  6296     __INST(lastErrorNumber) = nil;
  6306     __INST(lastErrorNumber) = nil;
  6297     if ((__INST(handleType) == nil)
  6307     if ((__INST(handleType) == nil)
  6298      || (__INST(handleType) == @symbol(filePointer))
  6308      || (__INST(handleType) == @symbol(filePointer))
  6299      || (__INST(handleType) == @symbol(socketFilePointer))
  6309      || (__INST(handleType) == @symbol(socketFilePointer))
  6300      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6310      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6301         OBJ fp;
  6311 	OBJ fp;
  6302         int _buffered = (__INST(buffered) == true);
  6312 	int _buffered = (__INST(buffered) == true);
  6303 
  6313 
  6304         if ((fp = __INST(handle)) != nil) {
  6314 	if ((fp = __INST(handle)) != nil) {
  6305             if (__INST(mode) != @symbol(readonly)) {
  6315 	    if (__INST(mode) != @symbol(readonly)) {
  6306                 if (1 /* _buffered */) {
  6316 		if (1 /* _buffered */) {
  6307                     FILEPOINTER f = __FILEVal(fp);
  6317 		    FILEPOINTER f = __FILEVal(fp);
  6308 #ifdef __win32__
  6318 #ifdef __win32__
  6309                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6319 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6310                         __win32_fflush(f);
  6320 			__win32_fflush(f);
  6311                     } else {
  6321 		    } else {
  6312                         int rslt;
  6322 			int rslt;
  6313 
  6323 
  6314                         do {
  6324 			do {
  6315                             __threadErrno = 0;
  6325 			    __threadErrno = 0;
  6316                             rslt = __STX_C_CALL1("fflush", fflush, f);
  6326 			    rslt = __STX_C_CALL1("fflush", fflush, f);
  6317                         } while((rslt < 0) && (__threadErrno == EINTR));
  6327 			} while((rslt < 0) && (__threadErrno == EINTR));
  6318                     }
  6328 		    }
  6319 #else /* ! __win32__ */
  6329 #else /* ! __win32__ */
  6320                     __BEGIN_INTERRUPTABLE__
  6330 		    __BEGIN_INTERRUPTABLE__
  6321                     FFLUSH(f);
  6331 		    FFLUSH(f);
  6322                     __END_INTERRUPTABLE__
  6332 		    __END_INTERRUPTABLE__
  6323 #endif /* ! __win32__ */
  6333 #endif /* ! __win32__ */
  6324                 }
  6334 		}
  6325             }
  6335 	    }
  6326         }
  6336 	}
  6327     }
  6337     }
  6328 %}
  6338 %}
  6329 
  6339 
  6330     "Modified: / 03-04-2019 / 16:15:11 / Claus Gittinger"
  6340     "Modified: / 03-04-2019 / 16:15:11 / Claus Gittinger"
  6331 !
  6341 !
  6340 #ifdef __SCHTEAM__
  6350 #ifdef __SCHTEAM__
  6341     STObject handle = self.instVarAt(I_handle);
  6351     STObject handle = self.instVarAt(I_handle);
  6342 
  6352 
  6343     if ((handle != STObject.Nil)
  6353     if ((handle != STObject.Nil)
  6344      && (aCharacter.isSTCharacter())) {
  6354      && (aCharacter.isSTCharacter())) {
  6345         handle.writeChar( aCharacter );
  6355 	handle.writeChar( aCharacter );
  6346         self.instVarAt_put(I_position, STObject.Nil);
  6356 	self.instVarAt_put(I_position, STObject.Nil);
  6347         return __c__._RETURN(aCharacter);
  6357 	return __c__._RETURN(aCharacter);
  6348     }
  6358     }
  6349 #else
  6359 #else
  6350     __INST(lastErrorNumber) = nil;
  6360     __INST(lastErrorNumber) = nil;
  6351     if ((__INST(handleType) == nil)
  6361     if ((__INST(handleType) == nil)
  6352      || (__INST(handleType) == @symbol(filePointer))
  6362      || (__INST(handleType) == @symbol(filePointer))
  6353      || (__INST(handleType) == @symbol(socketFilePointer))
  6363      || (__INST(handleType) == @symbol(socketFilePointer))
  6354      || (__INST(handleType) == @symbol(socketHandle))
  6364      || (__INST(handleType) == @symbol(socketHandle))
  6355      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6365      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6356         OBJ fp;
  6366 	OBJ fp;
  6357 
  6367 
  6358         if (((fp = __INST(handle)) != nil)
  6368 	if (((fp = __INST(handle)) != nil)
  6359          && (__INST(mode) != @symbol(readonly))
  6369 	 && (__INST(mode) != @symbol(readonly))
  6360         ) {
  6370 	) {
  6361             FILEPOINTER f = __FILEVal(fp);
  6371 	    FILEPOINTER f = __FILEVal(fp);
  6362             int _buffered = (__INST(buffered) == true);
  6372 	    int _buffered = (__INST(buffered) == true);
  6363             int cnt;
  6373 	    int cnt;
  6364             char buff[2];
  6374 	    char buff[2];
  6365             int nBytes = 1;
  6375 	    int nBytes = 1;
  6366 
  6376 
  6367             if (__INST(binary) != true) {
  6377 	    if (__INST(binary) != true) {
  6368                 if (__isCharacter(aCharacter)) {
  6378 		if (__isCharacter(aCharacter)) {
  6369                     unsigned int codePoint = __intVal(__characterVal(aCharacter));
  6379 		    unsigned int codePoint = __intVal(__characterVal(aCharacter));
  6370                     if (codePoint <= 0xFF) {
  6380 		    if (codePoint <= 0xFF) {
  6371                         unsigned char c = codePoint;
  6381 			unsigned char c = codePoint;
  6372                         buff[0] = c; nBytes = 1;
  6382 			buff[0] = c; nBytes = 1;
  6373 
  6383 
  6374                         if (c == '\n') {
  6384 			if (c == '\n') {
  6375                             OBJ mode = __INST(eolMode);
  6385 			    OBJ mode = __INST(eolMode);
  6376                             if (mode == @symbol(nl)) {
  6386 			    if (mode == @symbol(nl)) {
  6377                                 // no EOL translation
  6387 				// no EOL translation
  6378                             } else if (mode == nil) {
  6388 			    } else if (mode == nil) {
  6379                                 // no EOL translation
  6389 				// no EOL translation
  6380                             } else if (mode == @symbol(cr)) {
  6390 			    } else if (mode == @symbol(cr)) {
  6381                                 buff[0] = '\r';
  6391 				buff[0] = '\r';
  6382                             } else if (mode == @symbol(eot)) {
  6392 			    } else if (mode == @symbol(eot)) {
  6383                                 buff[0] = '\004';
  6393 				buff[0] = '\004';
  6384                             } else if (mode == @symbol(etx)) {
  6394 			    } else if (mode == @symbol(etx)) {
  6385                                 buff[0] = '\003';
  6395 				buff[0] = '\003';
  6386                             } else if (mode == @symbol(crlf)) {
  6396 			    } else if (mode == @symbol(crlf)) {
  6387                                 buff[0] = '\r';
  6397 				buff[0] = '\r';
  6388                                 buff[1] = '\n';
  6398 				buff[1] = '\n';
  6389                                 nBytes = 2;
  6399 				nBytes = 2;
  6390                             }
  6400 			    }
  6391                         }
  6401 			}
  6392     doWrite:
  6402     doWrite:
  6393                         if (! f) {
  6403 			if (! f) {
  6394                             fprintf(stderr, "oops - fileHandle is NULL in nextPut:\n");
  6404 			    fprintf(stderr, "oops - fileHandle is NULL in nextPut:\n");
  6395                             __INST(handle) = nil;
  6405 			    __INST(handle) = nil;
  6396                             goto out;
  6406 			    goto out;
  6397                         }
  6407 			}
  6398 
  6408 
  6399                         if (_buffered) {
  6409 			if (_buffered) {
  6400                             __WRITING__(f)
  6410 			    __WRITING__(f)
  6401                         }
  6411 			}
  6402 # ifdef __win32__
  6412 # ifdef __win32__
  6403                         if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6413 			if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6404                             cnt = __win32_fwrite(buff, 1, nBytes, f);
  6414 			    cnt = __win32_fwrite(buff, 1, nBytes, f);
  6405                         } else
  6415 			} else
  6406 # endif
  6416 # endif
  6407                         {
  6417 			{
  6408                             __WRITEBYTES__(cnt, f, buff, nBytes, _buffered, __INST(handleType));
  6418 			    __WRITEBYTES__(cnt, f, buff, nBytes, _buffered, __INST(handleType));
  6409                         }
  6419 			}
  6410                         if (cnt == nBytes) {
  6420 			if (cnt == nBytes) {
  6411                             if (__isSmallInteger(__INST(position))) {
  6421 			    if (__isSmallInteger(__INST(position))) {
  6412                                 INT np = __intVal(__INST(position)) + nBytes;
  6422 				INT np = __intVal(__INST(position)) + nBytes;
  6413                                 OBJ t;
  6423 				OBJ t;
  6414 
  6424 
  6415                                 t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6425 				t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6416                             } else {
  6426 			    } else {
  6417                                 __INST(position) = nil; /* i.e. do not know */
  6427 				__INST(position) = nil; /* i.e. do not know */
  6418                             }
  6428 			    }
  6419                             RETURN ( aCharacter );
  6429 			    RETURN ( aCharacter );
  6420                         }
  6430 			}
  6421 # ifdef __win32__
  6431 # ifdef __win32__
  6422                         __threadErrno = __WIN32_ERR(GetLastError());
  6432 			__threadErrno = __WIN32_ERR(GetLastError());
  6423 # endif
  6433 # endif
  6424                         error = __mkSmallInteger(__threadErrno);
  6434 			error = __mkSmallInteger(__threadErrno);
  6425                     }
  6435 		    }
  6426                 }
  6436 		}
  6427             } else {
  6437 	    } else {
  6428                 if (__isSmallInteger(aCharacter)) {
  6438 		if (__isSmallInteger(aCharacter)) {
  6429                     unsigned char c = __intVal(aCharacter);
  6439 		    unsigned char c = __intVal(aCharacter);
  6430                     buff[0] = c; nBytes = 1;
  6440 		    buff[0] = c; nBytes = 1;
  6431                     goto doWrite;
  6441 		    goto doWrite;
  6432                 }
  6442 		}
  6433             }
  6443 	    }
  6434         }
  6444 	}
  6435     }
  6445     }
  6436 out: ;
  6446 out: ;
  6437 #endif /* not SCHTEAM */
  6447 #endif /* not SCHTEAM */
  6438 %}.
  6448 %}.
  6439     error notNil ifTrue:[
  6449     error notNil ifTrue:[
  6440         lastErrorNumber := error.
  6450 	lastErrorNumber := error.
  6441         self writeError:error.
  6451 	self writeError:error.
  6442         ^ aCharacter
  6452 	^ aCharacter
  6443     ].
  6453     ].
  6444     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6454     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6445     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6455     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6446     binary == true ifTrue:[
  6456     binary == true ifTrue:[
  6447         aCharacter isInteger ifFalse:[
  6457 	aCharacter isInteger ifFalse:[
  6448             self argumentMustBeInteger.
  6458 	    self argumentMustBeInteger.
  6449             ^ aCharacter.
  6459 	    ^ aCharacter.
  6450         ].
  6460 	].
  6451     ] ifFalse:[
  6461     ] ifFalse:[
  6452         (aCharacter isCharacter not
  6462 	(aCharacter isCharacter not
  6453          or:[aCharacter codePoint > 16rFF]) ifTrue:[
  6463 	 or:[aCharacter codePoint > 16rFF]) ifTrue:[
  6454             self argumentMustBeCharacter.
  6464 	    self argumentMustBeCharacter.
  6455             ^ aCharacter.
  6465 	    ^ aCharacter.
  6456         ].
  6466 	].
  6457     ].
  6467     ].
  6458     "/ migration support
  6468     "/ migration support
  6459     self
  6469     self
  6460         nextPutByte:aCharacter asInteger
  6470 	nextPutByte:aCharacter asInteger
  6461         toFile:handle.
  6471 	toFile:handle.
  6462     ^ aCharacter
  6472     ^ aCharacter
  6463 
  6473 
  6464     "Modified: / 22-11-2018 / 14:47:13 / Stefan Vogel"
  6474     "Modified: / 22-11-2018 / 14:47:13 / Stefan Vogel"
  6465 !
  6475 !
  6466 
  6476 
  6475 #ifdef __SCHTEAM__
  6485 #ifdef __SCHTEAM__
  6476     STObject handle = self.instVarAt(I_handle);
  6486     STObject handle = self.instVarAt(I_handle);
  6477 
  6487 
  6478     if ((handle != STObject.Nil)
  6488     if ((handle != STObject.Nil)
  6479      && (aCollection.isSTString())) {
  6489      && (aCollection.isSTString())) {
  6480         handle.writeCharacters( aCollection.asSTString().characters );
  6490 	handle.writeCharacters( aCollection.asSTString().characters );
  6481         self.instVarAt_put(I_position, STObject.Nil);
  6491 	self.instVarAt_put(I_position, STObject.Nil);
  6482         return __c__._RETURN_self();
  6492 	return __c__._RETURN_self();
  6483     }
  6493     }
  6484 #else
  6494 #else
  6485 
  6495 
  6486     __INST(lastErrorNumber) = nil;
  6496     __INST(lastErrorNumber) = nil;
  6487 
  6497 
  6488     if ((__INST(handleType) == nil)
  6498     if ((__INST(handleType) == nil)
  6489      || (__INST(handleType) == @symbol(filePointer))
  6499      || (__INST(handleType) == @symbol(filePointer))
  6490      || (__INST(handleType) == @symbol(socketFilePointer))
  6500      || (__INST(handleType) == @symbol(socketFilePointer))
  6491      || (__INST(handleType) == @symbol(socketHandle))
  6501      || (__INST(handleType) == @symbol(socketHandle))
  6492      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6502      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  6493         OBJ fp;
  6503 	OBJ fp;
  6494 
  6504 
  6495         if (((fp = __INST(handle)) != nil)
  6505 	if (((fp = __INST(handle)) != nil)
  6496             && (__INST(mode) != @symbol(readonly))
  6506 	    && (__INST(mode) != @symbol(readonly))
  6497         ) {
  6507 	) {
  6498             INT len, cnt;
  6508 	    INT len, cnt;
  6499             INT o_offs;
  6509 	    INT o_offs;
  6500             FILEPOINTER f = __FILEVal(fp);
  6510 	    FILEPOINTER f = __FILEVal(fp);
  6501             int _buffered = (__INST(buffered) == true);
  6511 	    int _buffered = (__INST(buffered) == true);
  6502 
  6512 
  6503             if (! f) {
  6513 	    if (! f) {
  6504                 fprintf(stderr, "oops - fileHandle is NULL in nextPutAll:\n");
  6514 		fprintf(stderr, "oops - fileHandle is NULL in nextPutAll:\n");
  6505                 __INST(handle) = nil;
  6515 		__INST(handle) = nil;
  6506                 goto out;
  6516 		goto out;
  6507             }
  6517 	    }
  6508             if (_buffered) {
  6518 	    if (_buffered) {
  6509                 __WRITING__(f)
  6519 		__WRITING__(f)
  6510             }
  6520 	    }
  6511 
  6521 
  6512             if (__isStringLike(aCollection)) {
  6522 	    if (__isStringLike(aCollection)) {
  6513                 OBJ mode = __INST(eolMode);
  6523 		OBJ mode = __INST(eolMode);
  6514                 char *stringP = __stringVal(aCollection);
  6524 		char *stringP = __stringVal(aCollection);
  6515                 len = __stringSize(aCollection);
  6525 		len = __stringSize(aCollection);
  6516 
  6526 
  6517                 if (__INST(binary) != true
  6527 		if (__INST(binary) != true
  6518                     && ((mode == @symbol(cr))
  6528 		    && ((mode == @symbol(cr))
  6519                         || (mode == @symbol(etx))
  6529 			|| (mode == @symbol(etx))
  6520                         || (mode == @symbol(eot))
  6530 			|| (mode == @symbol(eot))
  6521                         || (mode == @symbol(crlf)))
  6531 			|| (mode == @symbol(crlf)))
  6522                     && memchr(stringP, '\n', len) != NULL)
  6532 		    && memchr(stringP, '\n', len) != NULL)
  6523                 {
  6533 		{
  6524                     // there is a '\n' to be translated, replace it into a buffer
  6534 		    // there is a '\n' to be translated, replace it into a buffer
  6525 
  6535 
  6526                     char *end;
  6536 		    char *end;
  6527                     char sep[2];
  6537 		    char sep[2];
  6528                     int sepLen = 1;
  6538 		    int sepLen = 1;
  6529                     int bufLen;
  6539 		    int bufLen;
  6530                     char *buf, *endBuf, *sp, *dp;
  6540 		    char *buf, *endBuf, *sp, *dp;
  6531 
  6541 
  6532                     sep[0] = '\n';
  6542 		    sep[0] = '\n';
  6533                     if (mode == @symbol(crlf)) {
  6543 		    if (mode == @symbol(crlf)) {
  6534                          sep[0] = '\r'; sep[1] = '\n'; sepLen = 2;
  6544 			 sep[0] = '\r'; sep[1] = '\n'; sepLen = 2;
  6535                     } else if (mode == @symbol(cr)) {
  6545 		    } else if (mode == @symbol(cr)) {
  6536                          sep[0] = '\r';
  6546 			 sep[0] = '\r';
  6537                     } else if (mode == @symbol(eot)) {
  6547 		    } else if (mode == @symbol(eot)) {
  6538                          sep[0] = '\004';
  6548 			 sep[0] = '\004';
  6539                     } else if (mode == @symbol(etx)) {
  6549 		    } else if (mode == @symbol(etx)) {
  6540                          sep[0] = '\003';
  6550 			 sep[0] = '\003';
  6541                     }
  6551 		    }
  6542 
  6552 
  6543                     // estimate size of buffer - assume every 4th char is a separator
  6553 		    // estimate size of buffer - assume every 4th char is a separator
  6544                     bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
  6554 		    bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
  6545                     buf = (char *)malloc(bufLen);
  6555 		    buf = (char *)malloc(bufLen);
  6546                     if (buf == NULL) {
  6556 		    if (buf == NULL) {
  6547                         error = __mkSmallInteger(ENOMEM);
  6557 			error = __mkSmallInteger(ENOMEM);
  6548                         goto out;
  6558 			goto out;
  6549                     }
  6559 		    }
  6550 
  6560 
  6551                     endBuf = buf + bufLen;
  6561 		    endBuf = buf + bufLen;
  6552                     end = stringP + len;
  6562 		    end = stringP + len;
  6553                     for (sp = stringP, dp = buf; sp < end; sp++) {
  6563 		    for (sp = stringP, dp = buf; sp < end; sp++) {
  6554                         char c;
  6564 			char c;
  6555 
  6565 
  6556                         if ((dp+sepLen) >= endBuf) {
  6566 			if ((dp+sepLen) >= endBuf) {
  6557                             char *newBuf;
  6567 			    char *newBuf;
  6558 
  6568 
  6559                             bufLen = bufLen * 2;
  6569 			    bufLen = bufLen * 2;
  6560                             newBuf = (char *)realloc(buf, bufLen);
  6570 			    newBuf = (char *)realloc(buf, bufLen);
  6561                             if (newBuf == NULL) {
  6571 			    if (newBuf == NULL) {
  6562                                 free(buf);
  6572 				free(buf);
  6563                                 error = __mkSmallInteger(ENOMEM);
  6573 				error = __mkSmallInteger(ENOMEM);
  6564                                 goto out;
  6574 				goto out;
  6565                             }
  6575 			    }
  6566                             endBuf = newBuf + bufLen;
  6576 			    endBuf = newBuf + bufLen;
  6567                             dp = newBuf + (dp-buf);
  6577 			    dp = newBuf + (dp-buf);
  6568                             buf = newBuf;
  6578 			    buf = newBuf;
  6569                         }
  6579 			}
  6570 
  6580 
  6571                         if ((c = *sp) != '\n') {
  6581 			if ((c = *sp) != '\n') {
  6572                             *dp++ = c;
  6582 			    *dp++ = c;
  6573                         } else {
  6583 			} else {
  6574                             *dp++ = sep[0];
  6584 			    *dp++ = sep[0];
  6575                             if (sepLen == 2) {
  6585 			    if (sepLen == 2) {
  6576                                 *dp++ = sep[1];
  6586 				*dp++ = sep[1];
  6577                             };
  6587 			    };
  6578                         }
  6588 			}
  6579                     }
  6589 		    }
  6580 
  6590 
  6581                     len = dp - buf;
  6591 		    len = dp - buf;
  6582 # ifdef __win32__
  6592 # ifdef __win32__
  6583                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6593 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6584                         cnt = __win32_fwrite(buf, 1, len, f);
  6594 			cnt = __win32_fwrite(buf, 1, len, f);
  6585                     } else
  6595 		    } else
  6586 # endif
  6596 # endif
  6587                     {
  6597 		    {
  6588                         __WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
  6598 			__WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
  6589                     }
  6599 		    }
  6590                     free(buf);
  6600 		    free(buf);
  6591                 } else  {  // No EOL conversion needed
  6601 		} else  {  // No EOL conversion needed
  6592 # ifdef __win32__
  6602 # ifdef __win32__
  6593                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6603 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6594                         cnt = __win32_fwrite(stringP, 1, len, f);
  6604 			cnt = __win32_fwrite(stringP, 1, len, f);
  6595                     } else
  6605 		    } else
  6596 # endif
  6606 # endif
  6597                     {
  6607 		    {
  6598                         o_offs = stringP - (char *)__InstPtr(aCollection);
  6608 			o_offs = stringP - (char *)__InstPtr(aCollection);
  6599                         __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6609 			__WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6600                     }
  6610 		    }
  6601                 }
  6611 		}
  6602             } else {   // Not a String
  6612 	    } else {   // Not a String
  6603                 if (__INST(binary) == true) {
  6613 		if (__INST(binary) == true) {
  6604                     INT offs;
  6614 		    INT offs;
  6605 
  6615 
  6606                     if (__isByteArrayLike(aCollection)) {
  6616 		    if (__isByteArrayLike(aCollection)) {
  6607                         offs = 0;
  6617 			offs = 0;
  6608                         len = __byteArraySize(aCollection);
  6618 			len = __byteArraySize(aCollection);
  6609                     } else if (__isBytes(aCollection)) {
  6619 		    } else if (__isBytes(aCollection)) {
  6610                         offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars));
  6620 			offs = __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(aCollection))->c_ninstvars));
  6611                         len = __byteArraySize(aCollection) - offs;
  6621 			len = __byteArraySize(aCollection) - offs;
  6612                     } else
  6622 		    } else
  6613                         goto out;
  6623 			goto out;
  6614 # ifdef __win32__
  6624 # ifdef __win32__
  6615                     if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6625 		    if ((f == __win32_stdout()) || (f == __win32_stderr())) {
  6616                         cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f);
  6626 			cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f);
  6617                     } else
  6627 		    } else
  6618 # endif
  6628 # endif
  6619                     {
  6629 		    {
  6620                         o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element) - (char *)__InstPtr(aCollection);
  6630 			o_offs = (char *)(__ByteArrayInstPtr(aCollection)->ba_element) - (char *)__InstPtr(aCollection);
  6621                         o_offs += offs;
  6631 			o_offs += offs;
  6622                         __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6632 			__WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
  6623                     }
  6633 		    }
  6624                 } else  // Not binary mode
  6634 		} else  // Not binary mode
  6625                     goto out;
  6635 		    goto out;
  6626             }
  6636 	    }
  6627 
  6637 
  6628             // Now check for errors
  6638 	    // Now check for errors
  6629             if (cnt == len) {
  6639 	    if (cnt == len) {
  6630                 if (__isSmallInteger(__INST(position))) {
  6640 		if (__isSmallInteger(__INST(position))) {
  6631                     INT np = __intVal(__INST(position)) + len;
  6641 		    INT np = __intVal(__INST(position)) + len;
  6632                     OBJ t;
  6642 		    OBJ t;
  6633 
  6643 
  6634                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6644 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  6635                 } else {
  6645 		} else {
  6636                     __INST(position) = nil; /* i.e. do not know */
  6646 		    __INST(position) = nil; /* i.e. do not know */
  6637                 }
  6647 		}
  6638                 RETURN (self);
  6648 		RETURN (self);
  6639             }
  6649 	    }
  6640 # ifdef __win32__
  6650 # ifdef __win32__
  6641             __threadErrno = __WIN32_ERR(GetLastError());
  6651 	    __threadErrno = __WIN32_ERR(GetLastError());
  6642 # endif
  6652 # endif
  6643             error = __mkSmallInteger(__threadErrno);
  6653 	    error = __mkSmallInteger(__threadErrno);
  6644             fprintf(stderr, "cnt=%"_ld_" len=%"_ld_"\n", (INT)cnt, (INT)len);
  6654 	    fprintf(stderr, "cnt=%"_ld_" len=%"_ld_"\n", (INT)cnt, (INT)len);
  6645         }
  6655 	}
  6646     }
  6656     }
  6647 out: ;
  6657 out: ;
  6648 #endif /* not SCHTEAM */
  6658 #endif /* not SCHTEAM */
  6649 %}.
  6659 %}.
  6650     error notNil ifTrue:[
  6660     error notNil ifTrue:[
  6651         lastErrorNumber := error.
  6661 	lastErrorNumber := error.
  6652         self writeError:error.
  6662 	self writeError:error.
  6653         ^ self
  6663 	^ self
  6654     ].
  6664     ].
  6655     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6665     handle isNil ifTrue:[self errorNotOpen. ^ self].
  6656     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6666     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  6657 
  6667 
  6658     super nextPutAll:aCollection
  6668     super nextPutAll:aCollection