ExternalStream.st
branchjv
changeset 19635 875eb54afd2c
parent 19572 90f8a4a7060a
parent 19622 c8edbe624b7c
child 19691 5e613f6255d9
equal deleted inserted replaced
19614:d8838105c692 19635:875eb54afd2c
       
     1 "{ Encoding: utf8 }"
       
     2 
     1 "
     3 "
     2  COPYRIGHT (c) 1988 by Claus Gittinger
     4  COPYRIGHT (c) 1988 by Claus Gittinger
     3 	      All Rights Reserved
     5 	      All Rights Reserved
     4 
     6 
     5  This software is furnished under a license and may be used
     7  This software is furnished under a license and may be used
  1539     ]
  1541     ]
  1540 !
  1542 !
  1541 
  1543 
  1542 initialize
  1544 initialize
  1543     OpenErrorSignal isNil ifTrue:[
  1545     OpenErrorSignal isNil ifTrue:[
  1544 	OpenErrorSignal := OpenError.
  1546         OpenErrorSignal := OpenError.
  1545 	OpenErrorSignal notifierString:'open error'.
  1547         OpenErrorSignal notifierString:'open error'.
  1546 
  1548 
  1547 	InvalidReadSignal := InvalidReadError.
  1549         InvalidReadSignal := InvalidReadError.
  1548 	InvalidReadSignal notifierString:'stream does not support reading'.
  1550         InvalidReadSignal notifierString:'stream does not support reading'.
  1549 
  1551 
  1550 	InvalidWriteSignal := InvalidWriteError.
  1552         InvalidWriteSignal := InvalidWriteError.
  1551 	InvalidWriteSignal notifierString:'stream does not support writing'.
  1553         InvalidWriteSignal notifierString:'stream does not support writing'.
  1552 
  1554 
  1553 	InvalidModeSignal := InvalidModeError.
  1555         InvalidModeSignal := InvalidModeError.
  1554 	InvalidModeSignal notifierString:'binary/text mode mismatch'.
  1556         InvalidModeSignal notifierString:'binary/text mode mismatch'.
  1555 
  1557 
  1556 	InvalidOperationSignal := InvalidOperationError.
  1558         InvalidOperationSignal := InvalidOperationError.
  1557 	InvalidOperationSignal notifierString:'unsupported file operation'.
  1559         InvalidOperationSignal notifierString:'unsupported file operation'.
  1558 
  1560 
  1559 	StreamNotOpenSignal := StreamNotOpenError.
  1561         StreamNotOpenSignal := StreamNotOpenError.
  1560 	StreamNotOpenSignal notifierString:'stream is not open'.
  1562         StreamNotOpenSignal notifierString:'stream is not open'.
  1561 
  1563 
  1562 	StreamIOErrorSignal := StreamIOError.
  1564         StreamIOErrorSignal := StreamIOError.
  1563 	StreamIOErrorSignal notifierString:'I/O error'.
  1565         StreamIOErrorSignal notifierString:'I/O error'.
       
  1566         
       
  1567         "/ self patchByteOrderOptimizedMethods
  1564     ].
  1568     ].
  1565 
  1569 
  1566     Lobby isNil ifTrue:[
  1570     Lobby isNil ifTrue:[
  1567 	Lobby := Registry new.
  1571         Lobby := Registry new.
  1568 
  1572 
  1569 	"want to get informed when returning from snapshot"
  1573         "want to get informed when returning from snapshot"
  1570 	ObjectMemory addDependent:self
  1574         ObjectMemory addDependent:self
  1571     ].
  1575     ].
  1572     DefaultEOLMode isNil ifTrue:[
  1576     DefaultEOLMode isNil ifTrue:[
  1573 	self initDefaultEOLMode.
  1577         self initDefaultEOLMode.
  1574     ].
  1578     ].
  1575     ReadMode isNil ifTrue:[
  1579     ReadMode isNil ifTrue:[
  1576 	self initModeStrings.
  1580         self initModeStrings.
  1577     ].
  1581     ].
  1578 
  1582 
  1579     "limit the amount of newspace to be used for non-tenurable executors to 5%"
  1583     "limit the amount of newspace to be used for non-tenurable executors to 5%"
  1580     "/ MaxNonTenurableExecutors := ObjectMemory newSpaceSize // (Socket sizeOfInst:0) // 20.
  1584     "/ MaxNonTenurableExecutors := ObjectMemory newSpaceSize // (Socket sizeOfInst:0) // 20.
  1581     "/ cg: changed because Socket is not in libbasic. Thus, standalone (libbasic only)
  1585     "/ cg: changed because Socket is not in libbasic. Thus, standalone (libbasic only)
  1582     "/ programs would fail to start.
  1586     "/ programs would fail to start.
  1583     MaxNonTenurableExecutors := (ObjectMemory newSpaceSize // 20 min:2000).
  1587     MaxNonTenurableExecutors := (ObjectMemory newSpaceSize // 20 min:2000).
  1584 
  1588 
  1585     "Modified: / 21.5.1998 / 16:33:53 / cg"
  1589     "Modified: / 21.5.1998 / 16:33:53 / cg"
       
  1590 !
       
  1591 
       
  1592 patchByteOrderOptimizedMethods
       
  1593     "EXPERIMENTAL (not yet done by default):
       
  1594      change the underlying implementation of
       
  1595         nextPutInt16MSB / nextPutInt16LSB
       
  1596         nextPutInt32MSB / nextPutInt32LSB
       
  1597      to the corresponding NATIVE methods."
       
  1598 
       
  1599     |native16 native32|
       
  1600     
       
  1601     native16 := self compiledMethodAt:#nextPutInt16NATIVE:.
       
  1602     native32 := self compiledMethodAt:#nextPutInt32NATIVE:.
       
  1603     
       
  1604     UninterpretedBytes isBigEndian ifTrue:[
       
  1605         (self compiledMethodAt:#nextPutInt16MSB:) code:(native16 code).
       
  1606         (self compiledMethodAt:#nextPutInt32MSB:) code:(native32 code).
       
  1607     ] ifFalse:[
       
  1608         (self compiledMethodAt:#nextPutInt16LSB:) code:(native16 code).
       
  1609         (self compiledMethodAt:#nextPutInt32LSB:) code:(native32 code).
       
  1610     ].
  1586 !
  1611 !
  1587 
  1612 
  1588 reOpenFiles
  1613 reOpenFiles
  1589     "reopen all files (if possible) after a snapShot load.
  1614     "reopen all files (if possible) after a snapShot load.
  1590      This is invoked via the #earlyRestart change notification."
  1615      This is invoked via the #earlyRestart change notification."
  4251     lastErrorNumber := error.
  4276     lastErrorNumber := error.
  4252     self writeError:error.
  4277     self writeError:error.
  4253 !
  4278 !
  4254 
  4279 
  4255 nextPutInt16:anIntegerOrCharacter MSB:msbFlag
  4280 nextPutInt16:anIntegerOrCharacter MSB:msbFlag
  4256     "Write the argument, anIntegerOrCharacter as a short (two bytes). If msbFlag is
  4281     "Write the argument, anIntegerOrCharacter as a short (two bytes). 
  4257      true, data is written most-significant byte first; otherwise least
  4282      If msbFlag is true, data is written most-significant byte first; 
  4258      first.
  4283      otherwise least first.
       
  4284      Notice that integers in the range -16r8000 to +16rFFFF can be written
       
  4285      (i.e. both signed and unsigned int32 values can be written.
  4259      Works in both binary and text modes."
  4286      Works in both binary and text modes."
  4260 
  4287 
  4261     |error|
  4288     |error|
  4262 %{
  4289 %{
  4263     int num;
  4290     int num;
  4264     union {
  4291     union {
  4265 	char bytes[2];
  4292         char bytes[2];
  4266 	short shortVal;
  4293         short shortVal;
  4267     } u;
  4294     } u;
  4268     OBJ fp;
  4295     OBJ fp;
  4269 
  4296 
  4270     __INST(lastErrorNumber) = nil;
  4297     __INST(lastErrorNumber) = nil;
  4271     if ((__INST(handleType) == nil)
  4298     if ((__INST(handleType) == nil)
  4272      || (__INST(handleType) == @symbol(filePointer))
  4299      || (__INST(handleType) == @symbol(filePointer))
  4273      || (__INST(handleType) == @symbol(socketFilePointer))
  4300      || (__INST(handleType) == @symbol(socketFilePointer))
  4274      || (__INST(handleType) == @symbol(socketHandle))
  4301      || (__INST(handleType) == @symbol(socketHandle))
  4275      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4302      || (__INST(handleType) == @symbol(pipeFilePointer))) {
  4276 	if (((fp = __INST(handle)) != nil)
  4303         if (((fp = __INST(handle)) != nil)
  4277 	 && (__INST(mode) != @symbol(readonly))
  4304          && (__INST(mode) != @symbol(readonly))
  4278 	) {
  4305         ) {
  4279 	    FILEPOINTER f = __FILEVal(fp);
  4306             FILEPOINTER f = __FILEVal(fp);
  4280 	    int _buffered = (__INST(buffered) == true);
  4307             int _buffered = (__INST(buffered) == true);
  4281 	    int cnt;
  4308             int cnt;
  4282 
  4309 
  4283 	    if (__isSmallInteger(anIntegerOrCharacter)) {
  4310             if (__isSmallInteger(anIntegerOrCharacter)) {
  4284 		num = __intVal(anIntegerOrCharacter);
  4311                 num = __intVal(anIntegerOrCharacter);
  4285 	    } else if (__isCharacter(anIntegerOrCharacter)) {
  4312             } else if (__isCharacter(anIntegerOrCharacter)) {
  4286 		num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4313                 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
  4287 	    } else
  4314             } else
  4288 		goto out;
  4315                 goto out;
  4289 
  4316 
  4290 	    if (msbFlag == true) {
  4317             if (msbFlag == true) {
  4291 #if defined(__MSBFIRST__)
  4318 #if defined(__MSBFIRST__)
  4292 		u.shortVal = num;
  4319                 u.shortVal = num;
  4293 #else
  4320 #else
  4294 		u.bytes[0] = (num >> 8) & 0xFF;
  4321                 u.bytes[0] = (num >> 8) & 0xFF;
  4295 		u.bytes[1] = num & 0xFF;
  4322                 u.bytes[1] = num & 0xFF;
  4296 #endif
  4323 #endif
  4297 	    } else {
  4324             } else {
  4298 #if defined(__LSBFIRST__)
  4325 #if defined(__LSBFIRST__)
  4299 		u.shortVal = num;
  4326                 u.shortVal = num;
  4300 #else
  4327 #else
  4301 		u.bytes[1] = (num >> 8) & 0xFF;
  4328                 u.bytes[1] = (num >> 8) & 0xFF;
  4302 		u.bytes[0] = num & 0xFF;
  4329                 u.bytes[0] = num & 0xFF;
  4303 #endif
  4330 #endif
  4304 	    }
  4331             }
  4305 
  4332 
  4306 	    if (_buffered) {
  4333             if (_buffered) {
  4307 		__WRITING__(f)
  4334                 __WRITING__(f)
  4308 	    }
  4335             }
  4309 	    __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4336             __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
  4310 
  4337 
  4311 	    if (cnt == 2) {
  4338             if (cnt == 2) {
  4312 		if (__isSmallInteger(__INST(position))) {
  4339                 if (__isSmallInteger(__INST(position))) {
  4313 		    INT np = __intVal(__INST(position)) + 2;
  4340                     INT np = __intVal(__INST(position)) + 2;
  4314 		    OBJ t;
  4341                     OBJ t;
  4315 
  4342 
  4316 		    t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4343                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
  4317 		} else {
  4344                 } else {
  4318 		    __INST(position) = nil; /* i.e. do not know */
  4345                     __INST(position) = nil; /* i.e. do not know */
  4319 		}
  4346                 }
  4320 		RETURN ( self );
  4347                 RETURN ( self );
  4321 	    }
  4348             }
  4322 	    __INST(position) = nil; /* i.e. do not know */
  4349             __INST(position) = nil; /* i.e. do not know */
  4323 	    error = __mkSmallInteger(__threadErrno);
  4350             error = __mkSmallInteger(__threadErrno);
  4324 	}
  4351         }
  4325     }
  4352     }
  4326 out:;
  4353 out:;
  4327 %}.
  4354 %}.
  4328     error notNil ifTrue:[
  4355     error notNil ifTrue:[
  4329 	lastErrorNumber := error.
  4356         lastErrorNumber := error.
  4330 	self writeError:error.
  4357         self writeError:error.
  4331 	^ self
  4358         ^ self
  4332     ].
  4359     ].
  4333     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4360     handle isNil ifTrue:[self errorNotOpen. ^ self].
  4334     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4361     (mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
  4335     self argumentMustBeInteger
  4362     self argumentMustBeInteger
  4336 !
  4363 !
  4337 
  4364 
       
  4365 nextPutInt16LSB:anIntegerOrCharacter
       
  4366     "do not remove.
       
  4367      See #patchByteOrderOptimizedMethods"
       
  4368      
       
  4369     self nextPutInt16:anIntegerOrCharacter MSB:false
       
  4370 !
       
  4371 
       
  4372 nextPutInt16MSB:anIntegerOrCharacter
       
  4373     "do not remove.
       
  4374      See #patchByteOrderOptimizedMethods"
       
  4375      
       
  4376     self nextPutInt16:anIntegerOrCharacter MSB:true
       
  4377 !
       
  4378 
       
  4379 nextPutInt16NATIVE:anIntegerOrCharacter 
       
  4380     "Write the argument, anIntegerOrCharacter as a short (two bytes) in native byte order. 
       
  4381      This is the CPU-specific byte order (LSB on x86, MSB on sparc, VAX and possibly on ARM).
       
  4382      Notice that integers in the range -16r8000 to +16rFFFF can be written
       
  4383      (i.e. both signed and unsigned int32 values can be written.
       
  4384      Works in both binary and text modes."
       
  4385 
       
  4386     |error|
       
  4387 %{
       
  4388     int num;
       
  4389     union {
       
  4390         char bytes[2];
       
  4391         short shortVal;
       
  4392     } u;
       
  4393     OBJ fp;
       
  4394 
       
  4395     __INST(lastErrorNumber) = nil;
       
  4396     if ((__INST(handleType) == nil)
       
  4397      || (__INST(handleType) == @symbol(filePointer))
       
  4398      || (__INST(handleType) == @symbol(socketFilePointer))
       
  4399      || (__INST(handleType) == @symbol(socketHandle))
       
  4400      || (__INST(handleType) == @symbol(pipeFilePointer))) {
       
  4401         if (((fp = __INST(handle)) != nil)
       
  4402          && (__INST(mode) != @symbol(readonly))
       
  4403         ) {
       
  4404             FILEPOINTER f = __FILEVal(fp);
       
  4405             int _buffered = (__INST(buffered) == true);
       
  4406             int cnt;
       
  4407 
       
  4408             if (__isSmallInteger(anIntegerOrCharacter)) {
       
  4409                 num = __intVal(anIntegerOrCharacter);
       
  4410             } else if (__isCharacter(anIntegerOrCharacter)) {
       
  4411                 num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
       
  4412             } else
       
  4413                 goto out;
       
  4414 
       
  4415             u.shortVal = num;
       
  4416 
       
  4417             if (_buffered) {
       
  4418                 __WRITING__(f)
       
  4419             }
       
  4420             __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
       
  4421 
       
  4422             if (cnt == 2) {
       
  4423                 if (__isSmallInteger(__INST(position))) {
       
  4424                     INT np = __intVal(__INST(position)) + 2;
       
  4425                     OBJ t;
       
  4426 
       
  4427                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
       
  4428                 } else {
       
  4429                     __INST(position) = nil; /* i.e. do not know */
       
  4430                 }
       
  4431                 RETURN ( self );
       
  4432             }
       
  4433             __INST(position) = nil; /* i.e. do not know */
       
  4434             error = __mkSmallInteger(__threadErrno);
       
  4435         }
       
  4436     }
       
  4437 out:;
       
  4438 %}.
       
  4439     self nextPutInt16:anIntegerOrCharacter MSB:(UninterpretedBytes isBigEndian).
       
  4440 !
       
  4441 
  4338 nextPutInt32:aNumber MSB:msbFlag
  4442 nextPutInt32:aNumber MSB:msbFlag
  4339     "Write the argument, aNumber as a long (four bytes). If msbFlag is
  4443     "Write the argument, aNumber as a long (four bytes). 
  4340      true, data is written most-significant byte first; otherwise least
  4444      If msbFlag is true, data is written most-significant byte first; 
  4341      first.
  4445      otherwise least first.
       
  4446      Notice that integers in the range -16r80000000 to +16rFFFFFFFF can be written
       
  4447      (i.e. both signed and unsigned int32 values can be written.
  4342      Works in both binary and text modes."
  4448      Works in both binary and text modes."
  4343 
  4449 
  4344     |error|
  4450     |error|
  4345 
  4451 
  4346 %{
  4452 %{
  4436 
  4542 
  4437     aNumber isInteger ifTrue:[
  4543     aNumber isInteger ifTrue:[
  4438         ^ super nextPutInt32:aNumber MSB:msbFlag
  4544         ^ super nextPutInt32:aNumber MSB:msbFlag
  4439     ].
  4545     ].
  4440     self argumentMustBeInteger
  4546     self argumentMustBeInteger
       
  4547 !
       
  4548 
       
  4549 nextPutInt32LSB:anIntegerOrCharacter
       
  4550     "do not remove.
       
  4551      See #patchByteOrderOptimizedMethods"
       
  4552      
       
  4553     self nextPutInt32:anIntegerOrCharacter MSB:false
       
  4554 !
       
  4555 
       
  4556 nextPutInt32MSB:anIntegerOrCharacter
       
  4557     "do not remove.
       
  4558      See #patchByteOrderOptimizedMethods"
       
  4559      
       
  4560     self nextPutInt32:anIntegerOrCharacter MSB:true
       
  4561 !
       
  4562 
       
  4563 nextPutInt32NATIVE:anInteger
       
  4564     "Write the argument, anInteger as a long (four bytes) in native byte order. 
       
  4565      This is the CPU-specific byte order (LSB on x86, MSB on sparc, VAX and possibly on ARM).
       
  4566      Notice that integers in the range -16r80000000 to +16rFFFFFFFF can be written
       
  4567      (i.e. both signed and unsigned int32 values can be written.
       
  4568      Works in both binary and text modes.
       
  4569      Notice: this message should not be sent explicitly by ANY program.
       
  4570              the following implementation replaces the code of either nextPutInt32MSB or LSB
       
  4571              dynamically (see #initialize on the class side)"
       
  4572 
       
  4573     |error|
       
  4574 
       
  4575 %{
       
  4576     int num;
       
  4577     union {
       
  4578         char bytes[4];
       
  4579         int intVal;
       
  4580     } u;
       
  4581     OBJ fp;
       
  4582 
       
  4583     __INST(lastErrorNumber) = nil;
       
  4584     if (__isSmallInteger(anInteger)) {
       
  4585         num = __intVal(anInteger);
       
  4586     } else {
       
  4587 #if __POINTER_SIZE__ == 8
       
  4588         // always more than 4-bytes
       
  4589         goto badArg;
       
  4590 #else
       
  4591         num = __longIntVal(anInteger);
       
  4592         if (num == 0) {
       
  4593             num = __signedLongIntVal(anInteger);
       
  4594             if (num == 0) {
       
  4595                 /* bad arg or out-of-range integer
       
  4596                  * (handled by the fallBack code)
       
  4597                  */
       
  4598                 goto badArg;
       
  4599             }
       
  4600         }
       
  4601 #endif
       
  4602     }
       
  4603 
       
  4604     if ((__INST(handleType) == nil)
       
  4605      || (__INST(handleType) == @symbol(filePointer))
       
  4606      || (__INST(handleType) == @symbol(socketFilePointer))
       
  4607      || (__INST(handleType) == @symbol(socketHandle))
       
  4608      || (__INST(handleType) == @symbol(pipeFilePointer))) {
       
  4609         if (((fp = __INST(handle)) != nil)
       
  4610          && (__INST(mode) != @symbol(readonly))
       
  4611         ) {
       
  4612             int _buffered = (__INST(buffered) == true);
       
  4613             FILEPOINTER f = __FILEVal(fp);
       
  4614             int cnt;
       
  4615 
       
  4616             u.intVal = num;
       
  4617             if (_buffered) {
       
  4618                 __WRITING__(f)
       
  4619             }
       
  4620             __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
       
  4621 
       
  4622             if (cnt == 4) {
       
  4623                 if (__isSmallInteger(__INST(position))) {
       
  4624                     INT np = __intVal(__INST(position)) + 4;
       
  4625                     OBJ t;
       
  4626 
       
  4627                     t = __MKINT(np); __INST(position) = t; __STORE(self, t);
       
  4628                 } else {
       
  4629                     __INST(position) = nil; /* i.e. do not know */
       
  4630                 }
       
  4631                 RETURN ( self );
       
  4632             }
       
  4633             __INST(position) = nil; /* i.e. do not know */
       
  4634             error = __mkSmallInteger(__threadErrno);
       
  4635         }
       
  4636     }
       
  4637 badArg: ;
       
  4638 %}.
       
  4639     self nextPutInt32:anInteger MSB:(UninterpretedBytes isBigEndian)
  4441 ! !
  4640 ! !
  4442 
  4641 
  4443 !ExternalStream methodsFor:'positioning'!
  4642 !ExternalStream methodsFor:'positioning'!
  4444 
  4643 
  4445 position
  4644 position
  6326     aString do:[:eachCharacter|
  6525     aString do:[:eachCharacter|
  6327 	self nextPutUtf8:eachCharacter.
  6526 	self nextPutUtf8:eachCharacter.
  6328     ].
  6527     ].
  6329 
  6528 
  6330     "
  6529     "
  6331 	'Bnnigheim' asUnicode16String errorPrintCR
  6530 	'Bönnigheim' asUnicode16String errorPrintCR
  6332     "
  6531     "
  6333 !
  6532 !
  6334 
  6533 
  6335 nextPutBytes:count from:anObject startingAt:start
  6534 nextPutBytes:count from:anObject startingAt:start
  6336     "write count bytes from an object starting at index start.
  6535     "write count bytes from an object starting at index start.
  6503 
  6702 
  6504     self nextPutUtf8:aCharacter.
  6703     self nextPutUtf8:aCharacter.
  6505 !
  6704 !
  6506 
  6705 
  6507 nextPutUtf16:aCharacter
  6706 nextPutUtf16:aCharacter
       
  6707     "append my UTF-16 MSB representation to the argument, aStream.
       
  6708      UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
       
  6709 
       
  6710     self nextPutUtf16:aCharacter MSB:true
       
  6711 
       
  6712     "
       
  6713         (FileStream newTemporary
       
  6714             nextPutUtf16:$B;
       
  6715             nextPutUtf16:$Ä;
       
  6716             nextPutUtf16:(Character codePoint:16r10CCCC);
       
  6717             reset;
       
  6718             binary;
       
  6719             contents)
       
  6720     "
       
  6721 !
       
  6722 
       
  6723 nextPutUtf16:aCharacter MSB:msb
  6508     "append my UTF-16 representation to the argument, aStream.
  6724     "append my UTF-16 representation to the argument, aStream.
  6509      UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
  6725      UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
  6510 
  6726 
  6511     |codePoint|
  6727     |codePoint|
  6512 
  6728 
  6513     codePoint := aCharacter codePoint.
  6729     codePoint := aCharacter codePoint.
  6514     (codePoint <= 16rD7FF
  6730     (codePoint <= 16rD7FF
  6515       or:[codePoint >= 16rE000 and:[codePoint <= 16rFFFF]]) ifTrue:[
  6731       or:[codePoint >= 16rE000 and:[codePoint <= 16rFFFF]]) ifTrue:[
  6516         self nextPutInt16:codePoint MSB:true.
  6732         self nextPutInt16:codePoint MSB:msb.
  6517     ] ifFalse:[codePoint <= 16r10FFFF ifTrue:[
  6733     ] ifFalse:[codePoint <= 16r10FFFF ifTrue:[
  6518         |highBits lowBits|
  6734         |highBits lowBits|
  6519 
  6735 
  6520         codePoint := codePoint - 16r100000.
  6736         codePoint := codePoint - 16r100000.
  6521         highBits := codePoint bitShift:-10.
  6737         highBits := codePoint bitShift:-10.
  6522         lowBits := codePoint bitAnd:16r3FF.
  6738         lowBits := codePoint bitAnd:16r3FF.
  6523         self nextPutInt16:highBits+16rD800 MSB:true.
  6739         self nextPutInt16:highBits+16rD800 MSB:msb.
  6524         self nextPutInt16:lowBits+16rDC00 MSB:true.
  6740         self nextPutInt16:lowBits+16rDC00 MSB:msb.
  6525     ] ifFalse:[
  6741     ] ifFalse:[
  6526         EncodingError raiseWith:aCharacter errorString:'Character cannot be encoded as UTF-16'.
  6742         EncodingError raiseWith:aCharacter errorString:'Character cannot be encoded as UTF-16'.
  6527     ]].
  6743     ]].
  6528 
  6744 
  6529     "
  6745     "
  6530         (FileStream newTemporary
  6746         (FileStream newTemporary
  6531             nextPutUtf16:$B;
  6747             nextPutUtf16:$B MSB:true;
  6532             nextPutUtf16:$;
  6748             nextPutUtf16:$Ä MSB:true;
  6533             nextPutUtf16:(Character codePoint:16r10CCCC);
  6749             nextPutUtf16:(Character codePoint:16r10CCCC) MSB:true;
       
  6750             reset;
       
  6751             binary;
       
  6752             contents)
       
  6753     
       
  6754         (FileStream newTemporary
       
  6755             nextPutUtf16:$B MSB:false;
       
  6756             nextPutUtf16:$Ä MSB:false;
       
  6757             nextPutUtf16:(Character codePoint:16r10CCCC) MSB:false;
  6534             reset;
  6758             reset;
  6535             binary;
  6759             binary;
  6536             contents)
  6760             contents)
  6537     "
  6761     "
  6538 !
  6762 !