ExternalStream.st
changeset 15987 0fbfbdf4a0a5
parent 15921 9941c0e5132a
child 15994 cbd013980da3
equal deleted inserted replaced
15986:387eab176223 15987:0fbfbdf4a0a5
  3318      architectures since it does not care for byte order or float representation."
  3318      architectures since it does not care for byte order or float representation."
  3319 
  3319 
  3320 %{
  3320 %{
  3321     FILEPOINTER f;
  3321     FILEPOINTER f;
  3322     int cnt, offs, ret, _buffered;
  3322     int cnt, offs, ret, _buffered;
  3323     int objSize, nInstVars, nInstBytes;
  3323     int objSize, nInstBytes;
  3324     char *cp;
  3324     char *cp;
  3325     char *extPtr;
  3325     char *extPtr;
  3326     OBJ fp;
  3326     OBJ fp;
  3327     int o_offs;
  3327     int o_offs;
  3328 
  3328 
  3329     __INST(lastErrorNumber) = nil;
  3329     __INST(lastErrorNumber) = nil;
  3330     if ((__INST(handleType) == nil)
  3330     if ((__INST(handleType) == nil)
  3331      || (__INST(handleType) == @symbol(filePointer))
  3331      || (__INST(handleType) == @symbol(filePointer))
  3332      || (__INST(handleType) == @symbol(socketFilePointer))
  3332      || (__INST(handleType) == @symbol(socketFilePointer))
  3333      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3333      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3334 	if (((fp = __INST(handle)) != nil)
  3334         if (((fp = __INST(handle)) != nil)
  3335 	    && (__INST(mode) != @symbol(writeonly))
  3335             && (__INST(mode) != @symbol(writeonly))
  3336 	    && __bothSmallInteger(count, start)
  3336             && __bothSmallInteger(count, start)
  3337 	) {
  3337         ) {
  3338 	    f = __FILEVal(fp);
  3338             f = __FILEVal(fp);
  3339 
  3339 
  3340 	    cnt = __intVal(count);
  3340             cnt = __intVal(count);
  3341 	    offs = __intVal(start) - 1;
  3341             offs = __intVal(start) - 1;
  3342 
  3342 
  3343 	    if (__isExternalBytesLike(anObject)) {
  3343             if (__isExternalBytesLike(anObject)) {
  3344 		OBJ sz;
  3344                 OBJ sz;
  3345 
  3345 
  3346 		nInstBytes = 0;
  3346                 nInstBytes = 0;
  3347 		extPtr = (char *)(__externalBytesAddress(anObject));
  3347                 extPtr = (char *)(__externalBytesAddress(anObject));
  3348 		if (extPtr == NULL) goto bad;
  3348                 if (extPtr == NULL) goto bad;
  3349 		sz = __externalBytesSize(anObject);
  3349                 sz = __externalBytesSize(anObject);
  3350 		if (__isSmallInteger(sz)) {
  3350                 if (__isSmallInteger(sz)) {
  3351 		    objSize = __intVal(sz);
  3351                     objSize = __intVal(sz);
  3352 		} else {
  3352                 } else {
  3353 		    objSize = 0; /* unknown */
  3353                     objSize = 0; /* unknown */
  3354 		}
  3354                 }
  3355 	    } else {
  3355             } else {
  3356 		OBJ oClass;
  3356                 OBJ oClass = __Class(anObject);
  3357 
  3357                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3358 		oClass = __Class(anObject);
  3358 
  3359 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3359                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3360 		    case BYTEARRAY:
  3360 
  3361 		    case WORDARRAY:
  3361                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3362 		    case LONGARRAY:
  3362                     case BYTEARRAY:
  3363 		    case SWORDARRAY:
  3363                     case WORDARRAY:
  3364 		    case SLONGARRAY:
  3364                     case LONGARRAY:
  3365 		    case FLOATARRAY:
  3365                     case SWORDARRAY:
  3366 		    case DOUBLEARRAY:
  3366                     case SLONGARRAY:
  3367 			break;
  3367                     case FLOATARRAY:
  3368 		    default:
  3368                     case DOUBLEARRAY:
  3369 			goto bad;
  3369 #ifdef __NEED_DOUBLE_ALIGN
  3370 		}
  3370                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3371 		extPtr = (char *)0;
  3371 #endif
  3372 		nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3372                         break;
  3373 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3373                     case LONGLONGARRAY:
  3374 		objSize = __Size(anObject) - nInstBytes;
  3374                     case SLONGLONGARRAY:
  3375 	    }
  3375 #ifdef __NEED_LONGLONG_ALIGN
  3376 
  3376                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3377 	    if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3377 #endif
  3378 		_buffered = (__INST(buffered) == true);
  3378                     default:
  3379 		if (_buffered) {
  3379                         goto bad;
  3380 		    __READING__(f);
  3380                 }
  3381 		}
  3381                 extPtr = (char *)0;
  3382 
  3382                 objSize = __Size(anObject) - nInstBytes;
  3383 		if (extPtr) {
  3383             }
  3384 		    __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3384 
  3385 		} else {
  3385             if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3386 		    /*
  3386                 _buffered = (__INST(buffered) == true);
  3387 		     * on interrupt, anObject may be moved to another location.
  3387                 if (_buffered) {
  3388 		     * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
  3388                     __READING__(f);
  3389 		     * to get a new address.
  3389                 }
  3390 		     */
  3390 
  3391 		    offs += nInstBytes;
  3391                 if (extPtr) {
  3392 		    __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3392                     __READAVAILBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3393 		}
  3393                 } else {
       
  3394                     /*
       
  3395                      * on interrupt, anObject may be moved to another location.
       
  3396                      * So we pass (char *)__InstPtr(anObject) + nInstBytes + offs to the macro __READ_BYTES__,
       
  3397                      * to get a new address.
       
  3398                      */
       
  3399                     offs += nInstBytes;
       
  3400                     __READAVAILBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
       
  3401                 }
  3394 #ifdef PRE_22_jan_2000
  3402 #ifdef PRE_22_jan_2000
  3395 		if (ret > 0)
  3403                 if (ret > 0)
  3396 #else
  3404 #else
  3397 		/* 0 is NOT an EOF condition here ... */
  3405                 /* 0 is NOT an EOF condition here ... */
  3398 		if (ret >= 0)
  3406                 if (ret >= 0)
  3399 #endif
  3407 #endif
  3400 		{
  3408                 {
  3401 		    if (__isSmallInteger(__INST(position))) {
  3409                     if (__isSmallInteger(__INST(position))) {
  3402 			INT np = __intVal(__INST(position)) + ret;
  3410                         INT np = __intVal(__INST(position)) + ret;
  3403 			OBJ t;
  3411                         OBJ t;
  3404 
  3412 
  3405 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3413                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3406 		    } else {
  3414                     } else {
  3407 			__INST(position) = nil; /* i.e. do not know */
  3415                         __INST(position) = nil; /* i.e. do not know */
  3408 		    }
  3416                     }
  3409 		    RETURN (__mkSmallInteger(ret));
  3417                     RETURN (__mkSmallInteger(ret));
  3410 		}
  3418                 }
  3411 #ifdef PRE_22_jan_2000
  3419 #ifdef PRE_22_jan_2000
  3412 		if (ret == 0) {
  3420                 if (ret == 0) {
  3413 		    __INST(hitEOF) = true;
  3421                     __INST(hitEOF) = true;
  3414 		} else /* ret < 0 */
  3422                 } else /* ret < 0 */
  3415 #endif
  3423 #endif
  3416 		{
  3424                 {
  3417 		    __INST(position) = nil;
  3425                     __INST(position) = nil;
  3418 		    __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  3426                     __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  3419 		}
  3427                 }
  3420 	    }
  3428             }
  3421 	}
  3429         }
  3422     }
  3430     }
  3423 bad: ;
  3431 bad: ;
  3424 %}.
  3432 %}.
  3425     (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0].
  3433     (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0].
  3426     lastErrorNumber notNil ifTrue:[^ self readError].
  3434     lastErrorNumber notNil ifTrue:[^ self readError].
  3510      since it does not care for byte order or float representation."
  3518      since it does not care for byte order or float representation."
  3511 
  3519 
  3512 %{
  3520 %{
  3513     FILEPOINTER f;
  3521     FILEPOINTER f;
  3514     int cnt, offs, ret, _buffered;
  3522     int cnt, offs, ret, _buffered;
  3515     int objSize, nInstVars, nInstBytes;
  3523     int objSize, nInstBytes;
  3516     char *extPtr;
  3524     char *extPtr;
  3517     OBJ fp;
  3525     OBJ fp;
  3518 
  3526 
  3519     __INST(lastErrorNumber) = nil;
  3527     __INST(lastErrorNumber) = nil;
  3520     if ((__INST(handleType) == nil)
  3528     if ((__INST(handleType) == nil)
  3521      || (__INST(handleType) == @symbol(filePointer))
  3529      || (__INST(handleType) == @symbol(filePointer))
  3522      || (__INST(handleType) == @symbol(socketFilePointer))
  3530      || (__INST(handleType) == @symbol(socketFilePointer))
  3523      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3531      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  3524 	if (((fp = __INST(handle)) != nil)
  3532         if (((fp = __INST(handle)) != nil)
  3525 	    && (__INST(mode) != @symbol(writeonly))
  3533             && (__INST(mode) != @symbol(writeonly))
  3526 	    && __bothSmallInteger(count, start)
  3534             && __bothSmallInteger(count, start)
  3527 	) {
  3535         ) {
  3528 	    f = __FILEVal(fp);
  3536             f = __FILEVal(fp);
  3529 
  3537 
  3530 	    cnt = __intVal(count);
  3538             cnt = __intVal(count);
  3531 	    offs = __intVal(start) - 1;
  3539             offs = __intVal(start) - 1;
  3532 
  3540 
  3533 	    if (__isExternalBytesLike(anObject)) {
  3541             if (__isExternalBytesLike(anObject)) {
  3534 		OBJ sz;
  3542                 OBJ sz;
  3535 
  3543 
  3536 		nInstBytes = 0;
  3544                 nInstBytes = 0;
  3537 		extPtr = (char *)(__externalBytesAddress(anObject));
  3545                 extPtr = (char *)(__externalBytesAddress(anObject));
  3538 		if (extPtr == NULL) goto bad;
  3546                 if (extPtr == NULL) goto bad;
  3539 		sz = __externalBytesSize(anObject);
  3547                 sz = __externalBytesSize(anObject);
  3540 		if (__isSmallInteger(sz)) {
  3548                 if (__isSmallInteger(sz)) {
  3541 		    objSize = __intVal(sz);
  3549                     objSize = __intVal(sz);
  3542 		} else {
  3550                 } else {
  3543 		    objSize = 0; /* unknown */
  3551                     objSize = 0; /* unknown */
  3544 		}
  3552                 }
  3545 	    } else {
  3553             } else {
  3546 		OBJ oClass;
  3554                 OBJ oClass = __Class(anObject);
  3547 
  3555                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3548 		oClass = __Class(anObject);
  3556 
  3549 		switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3557                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3550 		    case BYTEARRAY:
  3558                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  3551 		    case WORDARRAY:
  3559                     case BYTEARRAY:
  3552 		    case LONGARRAY:
  3560                     case WORDARRAY:
  3553 		    case SWORDARRAY:
  3561                     case LONGARRAY:
  3554 		    case SLONGARRAY:
  3562                     case SWORDARRAY:
  3555 		    case FLOATARRAY:
  3563                     case SLONGARRAY:
  3556 		    case DOUBLEARRAY:
  3564                     case FLOATARRAY:
  3557 			break;
  3565                     case DOUBLEARRAY:
  3558 		    default:
  3566 #ifdef __NEED_DOUBLE_ALIGN
  3559 			goto bad;
  3567                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
  3560 		}
  3568 #endif
  3561 		extPtr = (char *)0;
  3569                         break;
  3562 		nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3570                     case LONGLONGARRAY:
  3563 		nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  3571                     case SLONGLONGARRAY:
  3564 		objSize = __Size(anObject) - nInstBytes;
  3572 #ifdef __NEED_LONGLONG_ALIGN
  3565 	    }
  3573                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
  3566 	    if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3574 #endif
  3567 		_buffered = (__INST(buffered) == true);
  3575                     default:
  3568 		if (_buffered) {
  3576                         goto bad;
  3569 		    __READING__(f);
  3577                 }
  3570 		}
  3578                 extPtr = (char *)0;
  3571 
  3579                 objSize = __Size(anObject) - nInstBytes;
  3572 		if (extPtr) {
  3580             }
  3573 		    __READBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3581             if ((offs >= 0) && (cnt >= 0) && (objSize >= (cnt + offs))) {
  3574 		} else {
  3582                 _buffered = (__INST(buffered) == true);
  3575 		    /*
  3583                 if (_buffered) {
  3576 		     * on interrupt, anObject may be moved to another location.
  3584                     __READING__(f);
  3577 		     * So we pass anObject, and the offset to the __READBYTES_OBJ__ macro.
  3585                 }
  3578 		     */
  3586 
  3579 		    offs += nInstBytes;
  3587                 if (extPtr) {
  3580 		    __READBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3588                     __READBYTES__(ret, f, extPtr+offs, cnt, _buffered, __INST(handleType));
  3581 		}
  3589                 } else {
  3582 
  3590                     /*
  3583 		if (ret > 0) {
  3591                      * on interrupt, anObject may be moved to another location.
  3584 		    if (__isSmallInteger(__INST(position))) {
  3592                      * So we pass anObject, and the offset to the __READBYTES_OBJ__ macro.
  3585 			INT np = __intVal(__INST(position)) + ret;
  3593                      */
  3586 			OBJ t;
  3594                     offs += nInstBytes;
  3587 
  3595                     __READBYTES_OBJ__(ret, f, anObject, offs, cnt, _buffered, __INST(handleType));
  3588 			t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3596                 }
  3589 		    } else {
  3597 
  3590 			__INST(position) = nil; /* i.e. do not know */
  3598                 if (ret > 0) {
  3591 		    }
  3599                     if (__isSmallInteger(__INST(position))) {
  3592 		    RETURN (__mkSmallInteger(ret));
  3600                         INT np = __intVal(__INST(position)) + ret;
  3593 		}
  3601                         OBJ t;
  3594 		if (ret == 0) {
  3602 
  3595 		    __INST(hitEOF) = true;
  3603                         t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  3596 		} else /* ret < 0 */ {
  3604                     } else {
  3597 		    __INST(position) = nil;
  3605                         __INST(position) = nil; /* i.e. do not know */
  3598 		    __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
  3606                     }
  3599 		}
  3607                     RETURN (__mkSmallInteger(ret));
  3600 	    }
  3608                 }
  3601 	}
  3609                 if (ret == 0) {
       
  3610                     __INST(hitEOF) = true;
       
  3611                 } else /* ret < 0 */ {
       
  3612                     __INST(position) = nil;
       
  3613                     __INST(lastErrorNumber) = __mkSmallInteger(__threadErrno);
       
  3614                 }
       
  3615             }
       
  3616         }
  3602     }
  3617     }
  3603 bad: ;
  3618 bad: ;
  3604 %}.
  3619 %}.
  3605     (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0].
  3620     (hitEOF and:[self pastEndRead isNil]) ifTrue:[^ 0].
  3606     lastErrorNumber notNil ifTrue:[^ self readError].
  3621     lastErrorNumber notNil ifTrue:[^ self readError].
  4029         since it does not care for byte order or float representation."
  4044         since it does not care for byte order or float representation."
  4030 
  4045 
  4031 %{
  4046 %{
  4032     FILEPOINTER f;
  4047     FILEPOINTER f;
  4033     int cnt, len, offs, ret;
  4048     int cnt, len, offs, ret;
  4034     int objSize, nInstVars, nInstBytes, _buffered;
  4049     int objSize, nInstBytes, _buffered;
  4035     char *extPtr;
  4050     char *extPtr;
  4036     OBJ fp;
  4051     OBJ fp;
  4037 
  4052 
  4038     __INST(lastErrorNumber) = nil;
  4053     __INST(lastErrorNumber) = nil;
  4039     if ((__INST(handleType) == nil)
  4054     if ((__INST(handleType) == nil)
  4059                     objSize = __intVal(sz);
  4074                     objSize = __intVal(sz);
  4060                 } else {
  4075                 } else {
  4061                     objSize = 0; /* unknown */
  4076                     objSize = 0; /* unknown */
  4062                 }
  4077                 }
  4063             } else {
  4078             } else {
  4064                 OBJ oClass;
  4079                 OBJ oClass = __Class(anObject);
  4065 
  4080                 int nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  4066                 oClass = __Class(anObject);
  4081 
       
  4082                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
  4067                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  4083                 switch (__intVal(__ClassInstPtr(oClass)->c_flags) & ARRAYMASK) {
  4068                     case BYTEARRAY:
  4084                     case BYTEARRAY:
  4069                     case WORDARRAY:
  4085                     case WORDARRAY:
  4070                     case LONGARRAY:
  4086                     case LONGARRAY:
  4071                     case SWORDARRAY:
  4087                     case SWORDARRAY:
  4072                     case SLONGARRAY:
  4088                     case SLONGARRAY:
  4073                     case FLOATARRAY:
  4089                     case FLOATARRAY:
       
  4090                         break;
  4074                     case DOUBLEARRAY:
  4091                     case DOUBLEARRAY:
       
  4092 #ifdef __NEED_DOUBLE_ALIGN
       
  4093                         nInstBytes = (nInstBytes-1+__DOUBLE_ALIGN) &~ (__DOUBLE_ALIGN-1);
       
  4094 #endif
       
  4095                         break;
       
  4096                     case LONGLONGARRAY:
       
  4097                     case SLONGLONGARRAY:
       
  4098 #ifdef __NEED_LONGLONG_ALIGN
       
  4099                         nInstBytes = (nInstBytes-1+__LONGLONG_ALIGN) &~ (__LONGLONG_ALIGN-1);
       
  4100 #endif
  4075                         break;
  4101                         break;
  4076                     default:
  4102                     default:
  4077                         goto bad;
  4103                         goto bad;
  4078                 }
  4104                 }
  4079                 extPtr = (char *)0;
  4105                 extPtr = (char *)0;
  4080                 nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
       
  4081                 nInstBytes = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
       
  4082                 objSize = __Size(anObject) - nInstBytes;
  4106                 objSize = __Size(anObject) - nInstBytes;
  4083             }
  4107             }
  4084             if ( (offs >= 0) && (len >= 0) && (objSize >= (len + offs)) ) {
  4108             if ( (offs >= 0) && (len >= 0) && (objSize >= (len + offs)) ) {
  4085                 if (_buffered = (__INST(buffered) == true)) {
  4109                 if (_buffered = (__INST(buffered) == true)) {
  4086                     __WRITING__(f)
  4110                     __WRITING__(f)
  5830 ! !
  5854 ! !
  5831 
  5855 
  5832 !ExternalStream class methodsFor:'documentation'!
  5856 !ExternalStream class methodsFor:'documentation'!
  5833 
  5857 
  5834 version
  5858 version
  5835     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.378 2014-01-29 13:35:20 stefan Exp $'
  5859     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.379 2014-02-12 12:54:11 stefan Exp $'
  5836 !
  5860 !
  5837 
  5861 
  5838 version_CVS
  5862 version_CVS
  5839     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.378 2014-01-29 13:35:20 stefan Exp $'
  5863     ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.379 2014-02-12 12:54:11 stefan Exp $'
  5840 ! !
  5864 ! !
  5841 
  5865 
  5842 
  5866 
  5843 ExternalStream initialize!
  5867 ExternalStream initialize!