--- a/ByteArray.st Wed Apr 20 20:11:13 2016 +0100
+++ b/ByteArray.st Thu Apr 21 07:59:19 2016 +0100
@@ -165,6 +165,7 @@
+
!ByteArray class methodsFor:'queries'!
elementByteSize
@@ -2332,7 +2333,7 @@
reverse
"reverse the order of my elements inplace -
WARNING: this is a destructive operation, which modifies the receiver.
- Please use reversed (with a d) for a functional version.
+ Please use reversed (with a 'd' at the end) for a functional version.
Written as a primitive for speed on image manipulations (mirror)"
%{ /* NOCONTEXT */
@@ -2343,98 +2344,98 @@
OBJ cls;
if (__qClass(self) == @global(ByteArray)) {
- cnt = __byteArraySize(self);
- p1 = __ByteArrayInstPtr(self)->ba_element;
- p2 = p1 + cnt - 1;
+ cnt = __byteArraySize(self);
+ p1 = __ByteArrayInstPtr(self)->ba_element;
+ p2 = p1 + cnt - 1;
#if defined(__BSWAP)
- /*
- * can we use the bswap instruction ?
- * notice - not all CPUs have it (the HAS_BSWAP checks this).
- */
- if (__HAS_BSWAP()
- && ((cnt & 3) == 0)) {
- unsigned int *ip1, *ip2;
-
- ip1 = (unsigned int *)p1;
- ip2 = (unsigned int *)(p2 - 3);
-
- ip2 -= 7;
- while (ip1 <= ip2) {
- int t1, t2;
-
- t1 = ip1[0];
- t2 = ip2[7];
- ip2[7] = __BSWAP(t1);
- ip1[0] = __BSWAP(t2);
-
- t1 = ip1[1];
- t2 = ip2[6];
- ip2[6] = __BSWAP(t1);
- ip1[1] = __BSWAP(t2);
-
- t1 = ip1[2];
- t2 = ip2[5];
- ip2[5] = __BSWAP(t1);
- ip1[2] = __BSWAP(t2);
-
- t1 = ip1[3];
- t2 = ip2[4];
- ip2[4] = __BSWAP(t1);
- ip1[3] = __BSWAP(t2);
-
- ip1 += 4;
- ip2 -= 4;
- }
- ip2 += 7;
-
- while (ip1 < ip2) {
- int t;
-
- t = __BSWAP(*ip1);
- *ip1++ = __BSWAP(*ip2);
- *ip2-- = t;
- }
-
- if (ip1 == ip2) {
- int t;
- t = *ip1;
- t = __BSWAP(t);
- *ip1 = t;
- }
- RETURN ( self );
- }
-#endif /* __i386__ && __GNUC__ */
-
- p2 -= 7;
- while (p1 <= p2) {
- t = p1[0];
- p1[0] = p2[7];
- p2[7] = t;
-
- t = p1[1];
- p1[1] = p2[6];
- p2[6] = t;
-
- t = p1[2];
- p1[2] = p2[5];
- p2[5] = t;
-
- t = p1[3];
- p1[3] = p2[4];
- p2[4] = t;
-
- p1 += 4;
- p2 -= 4;
- }
- p2 += 7;
-
- while (p1 < p2) {
- t = *p1;
- *p1++ = *p2;
- *p2-- = t;
- }
- RETURN ( self );
+ /*
+ * can we use the bswap instruction ?
+ * notice - not all CPUs have it (the HAS_BSWAP checks this).
+ */
+ if (__HAS_BSWAP()
+ && ((cnt & 3) == 0)) {
+ unsigned int *ip1, *ip2;
+
+ ip1 = (unsigned int *)p1;
+ ip2 = (unsigned int *)(p2 - 3);
+
+ ip2 -= 7;
+ while (ip1 <= ip2) {
+ int t1, t2;
+
+ t1 = ip1[0];
+ t2 = ip2[7];
+ ip2[7] = __BSWAP(t1);
+ ip1[0] = __BSWAP(t2);
+
+ t1 = ip1[1];
+ t2 = ip2[6];
+ ip2[6] = __BSWAP(t1);
+ ip1[1] = __BSWAP(t2);
+
+ t1 = ip1[2];
+ t2 = ip2[5];
+ ip2[5] = __BSWAP(t1);
+ ip1[2] = __BSWAP(t2);
+
+ t1 = ip1[3];
+ t2 = ip2[4];
+ ip2[4] = __BSWAP(t1);
+ ip1[3] = __BSWAP(t2);
+
+ ip1 += 4;
+ ip2 -= 4;
+ }
+ ip2 += 7;
+
+ while (ip1 < ip2) {
+ int t;
+
+ t = __BSWAP(*ip1);
+ *ip1++ = __BSWAP(*ip2);
+ *ip2-- = t;
+ }
+
+ if (ip1 == ip2) {
+ int t;
+ t = *ip1;
+ t = __BSWAP(t);
+ *ip1 = t;
+ }
+ RETURN ( self );
+ }
+#endif /* __BSWAP (i.e. __i386__ && __GNUC__) */
+
+ p2 -= 7;
+ while (p1 <= p2) {
+ t = p1[0];
+ p1[0] = p2[7];
+ p2[7] = t;
+
+ t = p1[1];
+ p1[1] = p2[6];
+ p2[6] = t;
+
+ t = p1[2];
+ p1[2] = p2[5];
+ p2[5] = t;
+
+ t = p1[3];
+ p1[3] = p2[4];
+ p2[4] = t;
+
+ p1 += 4;
+ p2 -= 4;
+ }
+ p2 += 7;
+
+ while (p1 < p2) {
+ t = *p1;
+ *p1++ = *p2;
+ *p2-- = t;
+ }
+ RETURN ( self );
}
%}.
^ super reverse
@@ -2454,32 +2455,32 @@
(1 to:255) asByteArray reverse
1 to:1024 do:[:i|
- |bytes test rBytes|
-
- bytes := ((1 to:i) asArray collect:[:i | i bitAnd:255]) asByteArray.
- test := ((i to:1 by:-1) asArray collect:[:i | i bitAnd:255]) asByteArray.
- rBytes := bytes copy.
- rBytes reverse ~= test ifTrue:[
- self halt
- ].
- rBytes := bytes copy.
- rBytes reverse reverse ~= bytes ifTrue:[
- self halt
- ]
+ |bytes test rBytes|
+
+ bytes := ((1 to:i) asArray collect:[:i | i bitAnd:255]) asByteArray.
+ test := ((i to:1 by:-1) asArray collect:[:i | i bitAnd:255]) asByteArray.
+ rBytes := bytes copy.
+ rBytes reverse ~= test ifTrue:[
+ self halt
+ ].
+ rBytes := bytes copy.
+ rBytes reverse reverse ~= bytes ifTrue:[
+ self halt
+ ]
].
Time millisecondsToRun:[
- 10000000 timesRepeat:[
- #[1 2 3 4 5 6 7 8] reverse
- ]
+ 10000000 timesRepeat:[
+ #[1 2 3 4 5 6 7 8] reverse
+ ]
]
|b|
b := (0 to:255) asByteArray.
Time millisecondsToRun:[
- 10000000 timesRepeat:[
- b reverse
- ]
+ 10000000 timesRepeat:[
+ b reverse
+ ]
]
"
!
@@ -3062,7 +3063,6 @@
"
! !
-
!ByteArray methodsFor:'testing'!
isByteArray
@@ -3087,6 +3087,7 @@
"Modified: 22.4.1996 / 12:55:30 / cg"
! !
+
!ByteArray class methodsFor:'documentation'!
version
--- a/CharacterEncoderImplementations__ISO10646_to_UTF16BE.st Wed Apr 20 20:11:13 2016 +0100
+++ b/CharacterEncoderImplementations__ISO10646_to_UTF16BE.st Thu Apr 21 07:59:19 2016 +0100
@@ -254,7 +254,7 @@
!ISO10646_to_UTF16BE methodsFor:'private'!
nextPutTwoByteValue:anInteger to:aStream
- aStream nextPutInt16:anInteger MSB:true
+ aStream nextPutInt16MSB:anInteger
!
nextTwoByteValueFrom:aStream
--- a/CharacterEncoderImplementations__ISO10646_to_UTF16LE.st Wed Apr 20 20:11:13 2016 +0100
+++ b/CharacterEncoderImplementations__ISO10646_to_UTF16LE.st Thu Apr 21 07:59:19 2016 +0100
@@ -75,7 +75,7 @@
!ISO10646_to_UTF16LE methodsFor:'private'!
nextPutTwoByteValue:anInteger to:aStream
- aStream nextPutInt16:anInteger MSB:false
+ aStream nextPutInt16LSB:anInteger
!
nextTwoByteValueFrom:aStream
--- a/ExternalStream.st Wed Apr 20 20:11:13 2016 +0100
+++ b/ExternalStream.st Thu Apr 21 07:59:19 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -1541,39 +1543,41 @@
initialize
OpenErrorSignal isNil ifTrue:[
- OpenErrorSignal := OpenError.
- OpenErrorSignal notifierString:'open error'.
-
- InvalidReadSignal := InvalidReadError.
- InvalidReadSignal notifierString:'stream does not support reading'.
-
- InvalidWriteSignal := InvalidWriteError.
- InvalidWriteSignal notifierString:'stream does not support writing'.
-
- InvalidModeSignal := InvalidModeError.
- InvalidModeSignal notifierString:'binary/text mode mismatch'.
-
- InvalidOperationSignal := InvalidOperationError.
- InvalidOperationSignal notifierString:'unsupported file operation'.
-
- StreamNotOpenSignal := StreamNotOpenError.
- StreamNotOpenSignal notifierString:'stream is not open'.
-
- StreamIOErrorSignal := StreamIOError.
- StreamIOErrorSignal notifierString:'I/O error'.
+ OpenErrorSignal := OpenError.
+ OpenErrorSignal notifierString:'open error'.
+
+ InvalidReadSignal := InvalidReadError.
+ InvalidReadSignal notifierString:'stream does not support reading'.
+
+ InvalidWriteSignal := InvalidWriteError.
+ InvalidWriteSignal notifierString:'stream does not support writing'.
+
+ InvalidModeSignal := InvalidModeError.
+ InvalidModeSignal notifierString:'binary/text mode mismatch'.
+
+ InvalidOperationSignal := InvalidOperationError.
+ InvalidOperationSignal notifierString:'unsupported file operation'.
+
+ StreamNotOpenSignal := StreamNotOpenError.
+ StreamNotOpenSignal notifierString:'stream is not open'.
+
+ StreamIOErrorSignal := StreamIOError.
+ StreamIOErrorSignal notifierString:'I/O error'.
+
+ "/ self patchByteOrderOptimizedMethods
].
Lobby isNil ifTrue:[
- Lobby := Registry new.
-
- "want to get informed when returning from snapshot"
- ObjectMemory addDependent:self
+ Lobby := Registry new.
+
+ "want to get informed when returning from snapshot"
+ ObjectMemory addDependent:self
].
DefaultEOLMode isNil ifTrue:[
- self initDefaultEOLMode.
+ self initDefaultEOLMode.
].
ReadMode isNil ifTrue:[
- self initModeStrings.
+ self initModeStrings.
].
"limit the amount of newspace to be used for non-tenurable executors to 5%"
@@ -1585,6 +1589,27 @@
"Modified: / 21.5.1998 / 16:33:53 / cg"
!
+patchByteOrderOptimizedMethods
+ "EXPERIMENTAL (not yet done by default):
+ change the underlying implementation of
+ nextPutInt16MSB / nextPutInt16LSB
+ nextPutInt32MSB / nextPutInt32LSB
+ to the corresponding NATIVE methods."
+
+ |native16 native32|
+
+ native16 := self compiledMethodAt:#nextPutInt16NATIVE:.
+ native32 := self compiledMethodAt:#nextPutInt32NATIVE:.
+
+ UninterpretedBytes isBigEndian ifTrue:[
+ (self compiledMethodAt:#nextPutInt16MSB:) code:(native16 code).
+ (self compiledMethodAt:#nextPutInt32MSB:) code:(native32 code).
+ ] ifFalse:[
+ (self compiledMethodAt:#nextPutInt16LSB:) code:(native16 code).
+ (self compiledMethodAt:#nextPutInt32LSB:) code:(native32 code).
+ ].
+!
+
reOpenFiles
"reopen all files (if possible) after a snapShot load.
This is invoked via the #earlyRestart change notification."
@@ -4253,17 +4278,19 @@
!
nextPutInt16:anIntegerOrCharacter MSB:msbFlag
- "Write the argument, anIntegerOrCharacter as a short (two bytes). If msbFlag is
- true, data is written most-significant byte first; otherwise least
- first.
+ "Write the argument, anIntegerOrCharacter as a short (two bytes).
+ If msbFlag is true, data is written most-significant byte first;
+ otherwise least first.
+ Notice that integers in the range -16r8000 to +16rFFFF can be written
+ (i.e. both signed and unsigned int32 values can be written.
Works in both binary and text modes."
|error|
%{
int num;
union {
- char bytes[2];
- short shortVal;
+ char bytes[2];
+ short shortVal;
} u;
OBJ fp;
@@ -4273,72 +4300,151 @@
|| (__INST(handleType) == @symbol(socketFilePointer))
|| (__INST(handleType) == @symbol(socketHandle))
|| (__INST(handleType) == @symbol(pipeFilePointer))) {
- if (((fp = __INST(handle)) != nil)
- && (__INST(mode) != @symbol(readonly))
- ) {
- FILEPOINTER f = __FILEVal(fp);
- int _buffered = (__INST(buffered) == true);
- int cnt;
-
- if (__isSmallInteger(anIntegerOrCharacter)) {
- num = __intVal(anIntegerOrCharacter);
- } else if (__isCharacter(anIntegerOrCharacter)) {
- num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
- } else
- goto out;
-
- if (msbFlag == true) {
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(readonly))
+ ) {
+ FILEPOINTER f = __FILEVal(fp);
+ int _buffered = (__INST(buffered) == true);
+ int cnt;
+
+ if (__isSmallInteger(anIntegerOrCharacter)) {
+ num = __intVal(anIntegerOrCharacter);
+ } else if (__isCharacter(anIntegerOrCharacter)) {
+ num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
+ } else
+ goto out;
+
+ if (msbFlag == true) {
#if defined(__MSBFIRST__)
- u.shortVal = num;
+ u.shortVal = num;
#else
- u.bytes[0] = (num >> 8) & 0xFF;
- u.bytes[1] = num & 0xFF;
+ u.bytes[0] = (num >> 8) & 0xFF;
+ u.bytes[1] = num & 0xFF;
#endif
- } else {
+ } else {
#if defined(__LSBFIRST__)
- u.shortVal = num;
+ u.shortVal = num;
#else
- u.bytes[1] = (num >> 8) & 0xFF;
- u.bytes[0] = num & 0xFF;
+ u.bytes[1] = (num >> 8) & 0xFF;
+ u.bytes[0] = num & 0xFF;
#endif
- }
-
- if (_buffered) {
- __WRITING__(f)
- }
- __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
-
- if (cnt == 2) {
- if (__isSmallInteger(__INST(position))) {
- INT np = __intVal(__INST(position)) + 2;
- OBJ t;
-
- t = __MKINT(np); __INST(position) = t; __STORE(self, t);
- } else {
- __INST(position) = nil; /* i.e. do not know */
- }
- RETURN ( self );
- }
- __INST(position) = nil; /* i.e. do not know */
- error = __mkSmallInteger(__threadErrno);
- }
+ }
+
+ if (_buffered) {
+ __WRITING__(f)
+ }
+ __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
+
+ if (cnt == 2) {
+ if (__isSmallInteger(__INST(position))) {
+ INT np = __intVal(__INST(position)) + 2;
+ OBJ t;
+
+ t = __MKINT(np); __INST(position) = t; __STORE(self, t);
+ } else {
+ __INST(position) = nil; /* i.e. do not know */
+ }
+ RETURN ( self );
+ }
+ __INST(position) = nil; /* i.e. do not know */
+ error = __mkSmallInteger(__threadErrno);
+ }
}
out:;
%}.
error notNil ifTrue:[
- lastErrorNumber := error.
- self writeError:error.
- ^ self
+ lastErrorNumber := error.
+ self writeError:error.
+ ^ self
].
handle isNil ifTrue:[self errorNotOpen. ^ self].
(mode == #readonly) ifTrue:[self errorReadOnly. ^ self].
self argumentMustBeInteger
!
+nextPutInt16LSB:anIntegerOrCharacter
+ "do not remove.
+ See #patchByteOrderOptimizedMethods"
+
+ self nextPutInt16:anIntegerOrCharacter MSB:false
+!
+
+nextPutInt16MSB:anIntegerOrCharacter
+ "do not remove.
+ See #patchByteOrderOptimizedMethods"
+
+ self nextPutInt16:anIntegerOrCharacter MSB:true
+!
+
+nextPutInt16NATIVE:anIntegerOrCharacter
+ "Write the argument, anIntegerOrCharacter as a short (two bytes) in native byte order.
+ This is the CPU-specific byte order (LSB on x86, MSB on sparc, VAX and possibly on ARM).
+ Notice that integers in the range -16r8000 to +16rFFFF can be written
+ (i.e. both signed and unsigned int32 values can be written.
+ Works in both binary and text modes."
+
+ |error|
+%{
+ int num;
+ union {
+ char bytes[2];
+ short shortVal;
+ } u;
+ OBJ fp;
+
+ __INST(lastErrorNumber) = nil;
+ if ((__INST(handleType) == nil)
+ || (__INST(handleType) == @symbol(filePointer))
+ || (__INST(handleType) == @symbol(socketFilePointer))
+ || (__INST(handleType) == @symbol(socketHandle))
+ || (__INST(handleType) == @symbol(pipeFilePointer))) {
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(readonly))
+ ) {
+ FILEPOINTER f = __FILEVal(fp);
+ int _buffered = (__INST(buffered) == true);
+ int cnt;
+
+ if (__isSmallInteger(anIntegerOrCharacter)) {
+ num = __intVal(anIntegerOrCharacter);
+ } else if (__isCharacter(anIntegerOrCharacter)) {
+ num = __smallIntegerVal(__characterVal(anIntegerOrCharacter));
+ } else
+ goto out;
+
+ u.shortVal = num;
+
+ if (_buffered) {
+ __WRITING__(f)
+ }
+ __WRITEBYTES__(cnt, f, u.bytes, 2, _buffered, __INST(handleType));
+
+ if (cnt == 2) {
+ if (__isSmallInteger(__INST(position))) {
+ INT np = __intVal(__INST(position)) + 2;
+ OBJ t;
+
+ t = __MKINT(np); __INST(position) = t; __STORE(self, t);
+ } else {
+ __INST(position) = nil; /* i.e. do not know */
+ }
+ RETURN ( self );
+ }
+ __INST(position) = nil; /* i.e. do not know */
+ error = __mkSmallInteger(__threadErrno);
+ }
+ }
+out:;
+%}.
+ self nextPutInt16:anIntegerOrCharacter MSB:(UninterpretedBytes isBigEndian).
+!
+
nextPutInt32:aNumber MSB:msbFlag
- "Write the argument, aNumber as a long (four bytes). If msbFlag is
- true, data is written most-significant byte first; otherwise least
- first.
+ "Write the argument, aNumber as a long (four bytes).
+ If msbFlag is true, data is written most-significant byte first;
+ otherwise least first.
+ Notice that integers in the range -16r80000000 to +16rFFFFFFFF can be written
+ (i.e. both signed and unsigned int32 values can be written.
Works in both binary and text modes."
|error|
@@ -4438,6 +4544,99 @@
^ super nextPutInt32:aNumber MSB:msbFlag
].
self argumentMustBeInteger
+!
+
+nextPutInt32LSB:anIntegerOrCharacter
+ "do not remove.
+ See #patchByteOrderOptimizedMethods"
+
+ self nextPutInt32:anIntegerOrCharacter MSB:false
+!
+
+nextPutInt32MSB:anIntegerOrCharacter
+ "do not remove.
+ See #patchByteOrderOptimizedMethods"
+
+ self nextPutInt32:anIntegerOrCharacter MSB:true
+!
+
+nextPutInt32NATIVE:anInteger
+ "Write the argument, anInteger as a long (four bytes) in native byte order.
+ This is the CPU-specific byte order (LSB on x86, MSB on sparc, VAX and possibly on ARM).
+ Notice that integers in the range -16r80000000 to +16rFFFFFFFF can be written
+ (i.e. both signed and unsigned int32 values can be written.
+ Works in both binary and text modes.
+ Notice: this message should not be sent explicitly by ANY program.
+ the following implementation replaces the code of either nextPutInt32MSB or LSB
+ dynamically (see #initialize on the class side)"
+
+ |error|
+
+%{
+ int num;
+ union {
+ char bytes[4];
+ int intVal;
+ } u;
+ OBJ fp;
+
+ __INST(lastErrorNumber) = nil;
+ if (__isSmallInteger(anInteger)) {
+ num = __intVal(anInteger);
+ } else {
+#if __POINTER_SIZE__ == 8
+ // always more than 4-bytes
+ goto badArg;
+#else
+ num = __longIntVal(anInteger);
+ if (num == 0) {
+ num = __signedLongIntVal(anInteger);
+ if (num == 0) {
+ /* bad arg or out-of-range integer
+ * (handled by the fallBack code)
+ */
+ goto badArg;
+ }
+ }
+#endif
+ }
+
+ if ((__INST(handleType) == nil)
+ || (__INST(handleType) == @symbol(filePointer))
+ || (__INST(handleType) == @symbol(socketFilePointer))
+ || (__INST(handleType) == @symbol(socketHandle))
+ || (__INST(handleType) == @symbol(pipeFilePointer))) {
+ if (((fp = __INST(handle)) != nil)
+ && (__INST(mode) != @symbol(readonly))
+ ) {
+ int _buffered = (__INST(buffered) == true);
+ FILEPOINTER f = __FILEVal(fp);
+ int cnt;
+
+ u.intVal = num;
+ if (_buffered) {
+ __WRITING__(f)
+ }
+ __WRITEBYTES__(cnt, f, u.bytes, 4, _buffered, __INST(handleType));
+
+ if (cnt == 4) {
+ if (__isSmallInteger(__INST(position))) {
+ INT np = __intVal(__INST(position)) + 4;
+ OBJ t;
+
+ t = __MKINT(np); __INST(position) = t; __STORE(self, t);
+ } else {
+ __INST(position) = nil; /* i.e. do not know */
+ }
+ RETURN ( self );
+ }
+ __INST(position) = nil; /* i.e. do not know */
+ error = __mkSmallInteger(__threadErrno);
+ }
+ }
+badArg: ;
+%}.
+ self nextPutInt32:anInteger MSB:(UninterpretedBytes isBigEndian)
! !
!ExternalStream methodsFor:'positioning'!
@@ -6328,7 +6527,7 @@
].
"
- 'Bnnigheim' asUnicode16String errorPrintCR
+ 'Bönnigheim' asUnicode16String errorPrintCR
"
!
@@ -6505,6 +6704,23 @@
!
nextPutUtf16:aCharacter
+ "append my UTF-16 MSB representation to the argument, aStream.
+ UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
+
+ self nextPutUtf16:aCharacter MSB:true
+
+ "
+ (FileStream newTemporary
+ nextPutUtf16:$B;
+ nextPutUtf16:$Ä;
+ nextPutUtf16:(Character codePoint:16r10CCCC);
+ reset;
+ binary;
+ contents)
+ "
+!
+
+nextPutUtf16:aCharacter MSB:msb
"append my UTF-16 representation to the argument, aStream.
UTF-16 can encode only characters with code points between 0 to 16r10FFFF."
@@ -6513,24 +6729,32 @@
codePoint := aCharacter codePoint.
(codePoint <= 16rD7FF
or:[codePoint >= 16rE000 and:[codePoint <= 16rFFFF]]) ifTrue:[
- self nextPutInt16:codePoint MSB:true.
+ self nextPutInt16:codePoint MSB:msb.
] ifFalse:[codePoint <= 16r10FFFF ifTrue:[
|highBits lowBits|
codePoint := codePoint - 16r100000.
highBits := codePoint bitShift:-10.
lowBits := codePoint bitAnd:16r3FF.
- self nextPutInt16:highBits+16rD800 MSB:true.
- self nextPutInt16:lowBits+16rDC00 MSB:true.
+ self nextPutInt16:highBits+16rD800 MSB:msb.
+ self nextPutInt16:lowBits+16rDC00 MSB:msb.
] ifFalse:[
EncodingError raiseWith:aCharacter errorString:'Character cannot be encoded as UTF-16'.
]].
"
(FileStream newTemporary
- nextPutUtf16:$B;
- nextPutUtf16:$;
- nextPutUtf16:(Character codePoint:16r10CCCC);
+ nextPutUtf16:$B MSB:true;
+ nextPutUtf16:$Ä MSB:true;
+ nextPutUtf16:(Character codePoint:16r10CCCC) MSB:true;
+ reset;
+ binary;
+ contents)
+
+ (FileStream newTemporary
+ nextPutUtf16:$B MSB:false;
+ nextPutUtf16:$Ä MSB:false;
+ nextPutUtf16:(Character codePoint:16r10CCCC) MSB:false;
reset;
binary;
contents)
--- a/Float.st Wed Apr 20 20:11:13 2016 +0100
+++ b/Float.st Thu Apr 21 07:59:19 2016 +0100
@@ -496,6 +496,7 @@
^ Epsilon
! !
+
!Float class methodsFor:'binary storage'!
readBinaryIEEEDoubleFrom:aStream
@@ -529,12 +530,12 @@
"not part of libboss, as this is also used by others (TIFFReader)"
!
-readBinaryIEEEDoubleFrom:aStream into:aFloat
+readBinaryIEEEDoubleFrom:aStream into:aBasicNewFloat
"read the receiver's value from the binary stream, aStream,
interpreting the next bytes as an IEEE formatted 8-byte float.
The bytes are read in the native byte order (i.e.lsb on intel)"
- ^ self readBinaryIEEEDoubleFrom:aStream into:aFloat MSB:(UninterpretedBytes isBigEndian)
+ ^ self readBinaryIEEEDoubleFrom:aStream into:aBasicNewFloat MSB:(UninterpretedBytes isBigEndian)
!
readBinaryIEEEDoubleFrom:aStream into:aFloat MSB:msb
@@ -777,7 +778,6 @@
"
! !
-
!Float class methodsFor:'queries'!
exponentCharacter
@@ -843,7 +843,6 @@
^ 2 "must be careful here, whenever ST/X is used on VAX or a 370"
! !
-
!Float methodsFor:'arithmetic'!
* aNumber
@@ -2359,7 +2358,6 @@
"
! !
-
!Float methodsFor:'testing'!
isFinite
--- a/GenericException.st Wed Apr 20 20:11:13 2016 +0100
+++ b/GenericException.st Thu Apr 21 07:59:19 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1993 by Claus Gittinger
All Rights Reserved
@@ -238,7 +236,7 @@
!
handlerBlock
- "Compatibility with Signal. Class based exeptions do not have a handler
+ "Compatibility with Signal. Class based exceptions do not have a handler
block. They redefine the #action method instead"
^ nil
--- a/ShortFloat.st Wed Apr 20 20:11:13 2016 +0100
+++ b/ShortFloat.st Thu Apr 21 07:59:19 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1996 by Claus Gittinger
All Rights Reserved
@@ -348,6 +346,7 @@
^ Epsilon
! !
+
!ShortFloat class methodsFor:'binary storage'!
readBinaryIEEESingleFrom:aStream
@@ -384,22 +383,22 @@
"Modified: / 23-08-2006 / 16:01:47 / cg"
!
-readBinaryIEEESingleFrom:aStream into:aFloat
+readBinaryIEEESingleFrom:aStream into:aBasicNewShortFloat
"read a float value from the binary stream, aStream,
interpreting the next bytes as an IEEE formatted 4-byte float.
The bytes are read in the native byte order (i.e.lsb on intel)"
- ^ self readBinaryIEEESingleFrom:aStream into:aFloat MSB:(UninterpretedBytes isBigEndian)
+ ^ self readBinaryIEEESingleFrom:aStream into:aBasicNewShortFloat MSB:(UninterpretedBytes isBigEndian)
"Modified: / 23-08-2006 / 16:01:52 / cg"
!
-readBinaryIEEESingleFrom:aStream into:aFloat MSB:msb
+readBinaryIEEESingleFrom:aStream into:aBasicNewShortFloat MSB:msb
"read a float value from the binary stream, aStream,
interpreting the next bytes as an IEEE formatted 4-byte float.
If msb is true, the stream bytes are most-significant-first."
- aFloat class == self ifFalse:[self error:'no a ShortFloat'].
+ aBasicNewShortFloat class == self ifFalse:[self error:'no a ShortFloat'].
"
this implementation is wrong: does not work on non-IEEE machines
@@ -409,14 +408,14 @@
self isIEEEFormat ifFalse:[self error:'unsupported operation'].
(UninterpretedBytes isBigEndian == msb) ifFalse:[
- "swap the bytes"
- 4 to:1 by:-1 do:[:i |
- aFloat basicAt:i put:(aStream next)
- ].
- ^ self
+ "swap the bytes"
+ 4 to:1 by:-1 do:[:i |
+ aBasicNewShortFloat basicAt:i put:(aStream next)
+ ].
+ ^ self
].
1 to:4 do:[:i |
- aFloat basicAt:i put:aStream next
+ aBasicNewShortFloat basicAt:i put:aStream next
]
"not part of libboss, as this is also used by others (TIFFReader)"
--- a/Stream.st Wed Apr 20 20:11:13 2016 +0100
+++ b/Stream.st Thu Apr 21 07:59:19 2016 +0100
@@ -1010,7 +1010,7 @@
!
nextIEEEDouble
- "read an 8-byte IEEE double precision float number"
+ "read an 8-byte IEEE double precision float number in native byte order"
^ Float readBinaryIEEEDoubleFrom:self
!
@@ -1022,7 +1022,7 @@
!
nextIEEESingle
- "read a 4-byte IEEE single precision float number"
+ "read a 4-byte IEEE single precision float number in native byte order"
^ ShortFloat readBinaryIEEESingleFrom:self
!
@@ -2010,7 +2010,11 @@
!
nextPutAllUtf16:aString
- "write a string as UTF-16 bytes"
+ "write a string as UTF-16 characters.
+ Notice: this writes characters - not bytes.
+ The underlying stream must be a stream which can deal with characters,
+ eg. OrderedCollectionStream, TwoByteCharacterStream, etc.
+ Also notice, that characters above 16rFFFF are escaped according UTF16 sepcifications."
|sz "{Class: SmallInteger}"|
@@ -2020,6 +2024,18 @@
].
!
+nextPutAllUtf16Bytes:aString MSB:msb
+ "write a string as UTF-16 bytes - no 0-word is written.
+ The underlying stream must support writing of bytes"
+
+ |sz "{Class: SmallInteger}"|
+
+ sz := aString size.
+ 1 to:sz do:[:idx|
+ self nextPutInt16:(aString at:idx) codePoint MSB:msb.
+ ].
+!
+
nextPutAllUtf8:aString
"normal streams can not handle multi-byte characters, so convert them to utf8"
@@ -2406,8 +2422,10 @@
nextPutUtf16:aCharacter
"append my UTF-16 representation to the argument, aStream.
- UTF-16 can encode only characters with code points between 0 to 16r10FFFF.
- The collection must be able to store 2-byte values (TwoByteString, OrderedCollection)"
+ Notice: this writes characters - not bytes.
+ The underlying stream must be a stream which can deal with characters,
+ eg. OrderedCollectionStream, TwoByteCharacterStream, etc.
+ Also notice, that characters above 16rFFFF are escaped according UTF16 sepcifications."
|codePoint "{Class: SmallInteger}"|
@@ -2438,6 +2456,7 @@
nextPutUtf8:aCharacter
"append my UTF-8 representation to the argument, aStream.
+ The underlying stream must be a stream which can deal with characters.
Up to 31 bits can be encoded in up to 6 bytes.
However, currently, characters are limited to 31 bits."
--- a/Timestamp.st Wed Apr 20 20:11:13 2016 +0100
+++ b/Timestamp.st Thu Apr 21 07:59:19 2016 +0100
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -17,7 +15,7 @@
AbstractTime subclass:#Timestamp
instanceVariableNames:'osTime'
- classVariableNames:'Epoch MinOSTime MaxOSTime'
+ classVariableNames:'Epoch MinOSTime MaxOSTime TimeZoneInfo'
poolDictionaries:''
category:'Magnitude-Time'
!
@@ -1447,155 +1445,161 @@
It is recommended to add explicit information in the form of +hh:mm to a printed
representation, instead of using names.
- As this is searched for when reverse converting from utcOffset to TZName,
- and we do not want to care for summer time, make sure that all summer times are at
- the end so they match last."
-
+ As this is searched for when reverse converting from utcOffset to TZName"
+
+ "/ the table below can be customized via a setter,
+ "/ if an application knows better
+ "/ (reading a system timeZone table, or limiting the table to military/non-military names only, for example)
+
+ TimeZoneInfo notNil ifTrue:[^ TimeZoneInfo].
+
+ "/ table is name, utcOffset(minutes), DST-flag, startDay, endDay
^ #(
- 'Z' 0 "/ zulu
- 'UTC' 0
- 'GMT' 0
+ 'Z' 0 false "/ zulu
+ 'UTC' 0 false
+ 'GMT' 0 false
"/ US
- 'HAST' -10 "/ hawai standard
- 'AKST' -9 "/ alaska standard
- 'YST' -9 "/ yukon standard
- 'PST' -8 "/ pacific standard
- 'PT' -8 "/ pacific standard
- 'MST' -7 "/ mountain standard
- 'CST' -6 "/ central standard
- 'EST' -5 "/ eastern standard
- 'AST' -4 "/ atlantic standard
-
- 'NST' -3.5 "/ new foundland standard
- 'PMST' -3 "/ pierre & miquelon
- 'WGT' -3 "/ west greenland
- 'EGT' -1 "/ east greenland
+ 'HAST' -600 false "/ hawai standard
+ 'AKST' -540 false "/ alaska standard
+ 'YST' -540 false "/ yukon standard
+ 'PST' -480 false "/ pacific standard
+ 'PT' -480 false "/ pacific standard
+ 'MST' -420 false "/ mountain standard
+ 'CST' -360 false "/ central standard
+ 'EST' -300 false "/ eastern standard
+ 'AST' -240 false "/ atlantic standard
+
+ 'NST' -210 false "/ new foundland standard
+ 'PMST' -180 false "/ pierre & miquelon
+ 'WGT' -180 false "/ west greenland
+ 'EGT' -60 false "/ east greenland
"/ europe
- 'CET' 1 "/ central european
- 'EET' 2 "/ east european
- 'WET' 0 "/ west european
+ 'CET' 60 false "/ central european
+ 'EET' 120 false "/ east european
+ 'WET' 0 false "/ west european
"/ conflict with india!!
"/ 'IST' 1 "/ irish standard time
"/ 'IST' 1 "/ israel standard time
- 'AZOT' -1 "/ azores standard
-
- 'MSK' 4 "/ moscow european
- 'MSD' 4
- 'BT' 4 "/ baghdad
+ 'AZOT' -60 false "/ azores standard
+
+ 'MSK' 240 false "/ moscow european
+ 'MSD' 240 false
+ 'BT' 240 false "/ baghdad
"/ pacific
- 'NZST' 12 "/ new zealand standard
- 'FJT' 12 "/ fiji
+ 'NZST' 720 false "/ new zealand standard
+ 'FJT' 720 false "/ fiji
"/ south america
- 'ART' -3 "/ argentina
- 'BOT' -4 "/ bolivia
- 'BRT' -3 "/ brasilia
- 'CLT' -4 "/ chile
- 'ECT' -5 "/ equador
- 'PET' -5 "/ peru
- 'PYT' -4 "/ paraguay
- 'UYT' -3 "/ uruguay
- 'VET' -4.5 "/ venezuela standard
- 'VST' -4.5 "/ venezuela standard
+ 'ART' -180 false "/ argentina
+ 'BOT' -240 false "/ bolivia
+ 'BRT' -180 false "/ brasilia
+ 'CLT' -240 false "/ chile
+ 'ECT' -300 false "/ equador
+ 'PET' -300 false "/ peru
+ 'PYT' -240 false "/ paraguay
+ 'UYT' -180 false "/ uruguay
+ 'VET' -270 false "/ venezuela standard
+ 'VST' -270 false "/ venezuela standard
"/ africa
- 'CAT' 2 "/ central africa
- 'EAT' 3 "/ east africa
- 'SAST' 2 "/ south africa standard
- 'WAT' 1 "/ west africa
- 'WT' 0 "/ west sahara standard
-
- 'AST' 3 "/ arabia
- 'IRT' 3.5 "/ iran time
- 'AFT' 4.5 "/ afghanistan time
-
- 'HKT' 8 "/ hongkong
- 'IST' 5.5 "/ india standard
- 'ICT' 7 "/ indochina
- 'CNST' 8 "/ china standard
- 'JST' 9 "/ japan standard
- 'KST' 9 "/ korea standard
- 'SGT' 8 "/ singapore
- 'MYT' 8 "/ malaysia
- 'AWST' 8 "/ australian west standard
- 'ACWST' 8.75 "/ australian central western standard
- 'ACST' 9.5 "/ australian central standard
- 'AEST' 10 "/ australian east standard
- 'NFT' 11.5 "/ norfolk island, australia
-
- 'CHAST' 12.75 "/ chatham island standard
- 'WST' 13 "/ west samoa - yes thats 13!!
- 'TOT' 13 "/ tonga - yes thats 13!!
- 'TKT' 13 "/ tokelau - yes thats 13!!
- 'LINT' 14 "/ line islands - yes thats 14!!
+ 'CAT' 120 false "/ central africa
+ 'EAT' 180 false "/ east africa
+ 'SAST' 120 false "/ south africa standard
+ 'WAT' 60 false "/ west africa
+ 'WT' 0 false "/ west sahara standard
+
+ 'AST' 180 false "/ arabia
+ 'IRT' 210 false "/ iran time
+ 'AFT' 270 false "/ afghanistan time
+
+ 'HKT' 480 false "/ hongkong
+ 'IST' 330 false "/ india standard
+ 'ICT' 420 false "/ indochina
+ 'CNST' 480 false "/ china standard
+ 'JST' 540 false "/ japan standard
+ 'KST' 540 false "/ korea standard
+ 'SGT' 480 false "/ singapore
+ 'MYT' 480 false "/ malaysia
+ 'AWST' 480 false "/ australian west standard
+ 'ACWST' 525 false "/ australian central western standard
+ 'ACST' 570 false "/ australian central standard
+ 'AEST' 600 false "/ australian east standard
+ 'NFT' 690 false "/ norfolk island, australia
+
+ 'CHAST' 765 false "/ chatham island standard
+ 'WST' 780 false "/ west samoa - yes thats 13!!
+ 'TOT' 780 false "/ tonga - yes thats 13!!
+ 'TKT' 780 false "/ tokelau - yes thats 13!!
+ 'LINT' 840 false "/ line islands - yes thats 14!!
"/ misc
- 'IDLW' -12 "/ international date line west
- 'IDLE' 12 "/ international date line east
+ 'IDLW' -720 false "/ international date line west
+ 'IDLE' 720 false "/ international date line east
+
+ 'MEZ' 60 false "/ mittel europäische Zeit / central european (german)
+ 'MESZ' 120 true "/ central european summer (german)
+ 'WESZ' 60 true "/ west european summer (german)
+
+ 'WEZ' 0 false "/ west european (german)
+
+ 'HADT' -540 true "/ hawaii summer
+ 'ADT' -180 true
+ 'AKDT' -540 true "/ alaska summer
+ 'YDT' -480 true "/ yukon summer
+ 'PDT' -420 true "/ pacific daylight saving
+ 'MDT' -360 true "/ mountain daylight saving
+ 'CDT' -300 true "/ central daylight saving
+ 'EDT' -240 true "/ eastern daylight saving
+ 'CLST' -180 true "/ chile summer
+ 'NDT' -150 true
+ 'PMDT' -120 true
+ 'BRST' -120 true "/ brasilia summer
+ 'WGST' -120 true "/ west greenland summer
+ 'EGST' 0 true "/ east greenland summer
+ 'AZOST' 0 true "/ azores summer
+ 'EEST' 180 true
+ 'CEST' 120 true
+ 'WAST' 120 true "/ west africa summer
+ "/ 'WST' 60 true "/ west sahara summer - conflict with west samoa
+ 'WEST' 60 true
+ 'BST' 60 true "/ british summer time
+ 'IRST' 270 true "/ iran summer time
+ 'AWDT' 540 true "/ australian west daylight saving
+ 'ACDT' 630 true "/ australian central daylight saving
+ 'AEDT' 660 true "/ australian east daylight saving
+ 'CHADT' 825 true "/ chatham island daylight saving
+ 'FJST' 780 true "/ fiji summer
+ 'NZDT' 780 true "/ new zealand summer
"/ military
- 'A' 1 "/ alpha
- 'B' 2 "/ bravo
- 'C' 3 "/ charlie
- 'D' 4 "/ delta
- 'E' 5 "/ echo
- 'F' 6 "/ foxtrot
- 'G' 7 "/ golf
- 'H' 8 "/ hotel
- 'I' 9 "/ also called india - how misleading
- 'K' 10 "/ kilo
- 'L' 11 "/ lima - but not there
- 'M' 12 "/ mike
- 'N' -1 "/ november (but also in other months)
- 'O' -2 "/ oscar
- 'P' -3 "/ papa (not mama)
- 'Q' -4 "/ quebec - really?
- 'R' -5 "/ romeo and juliet
- 'S' -6 "/ sierra
- 'T' -7 "/ tango (&rumba)
- 'U' -8 "/ uniform
- 'V' -9 "/ victor
- 'W' -10 "/ whiskey (scotch?)
- 'X' -11 "/ xray
- 'Y' -12 "/ yankee
-
- 'MEZ' 1 "/ central european (german)
- 'MESZ' 2 "/ central european summer (german)
- 'WESZ' 1 "/ west european summer (german)
-
- 'WEZ' 0 "/ west european (german)
-
- 'HADT' -9 "/ hawaii summer
- 'ADT' -3
- 'AKDT' -9 "/ alaska summer
- 'YDT' -8 "/ yukon summer
- 'PDT' -7 "/ pacific daylight saving
- 'MDT' -6 "/ mountain daylight saving
- 'CDT' -5 "/ central daylight saving
- 'EDT' -4 "/ eastern daylight saving
- 'CLST' -3 "/ chile summer
- 'NDT' -2.5
- 'PMDT' -2
- 'BRST' -2 "/ brasilia summer
- 'WGST' -2 "/ west greenland summer
- 'EGST' 0 "/ east greenland summer
- 'AZOST' 0 "/ azores summer
- 'EEST' 3
- 'CEST' 2
- 'WAST' 2 "/ west africa summer
- "/ 'WST' 1 "/ west sahara summer - conflict with west samoa
- 'WEST' 1
- 'BST' 1 "/ british summer time
- 'IRST' 4.5 "/ iran summer time
- 'AWDT' 9 "/ australian west daylight saving
- 'ACDT' 10.5 "/ australian central daylight saving
- 'AEDT' 11 "/ australian east daylight saving
- 'CHADT' 13.75 "/ chatham island daylight saving
- 'FJST' 13 "/ fiji summer
- 'NZDT' 13 "/ new zealand summer
+ 'A' 60 false "/ alpha
+ 'B' 120 false "/ bravo
+ 'C' 180 false "/ charlie
+ 'D' 240 false "/ delta
+ 'E' 300 false "/ echo
+ 'F' 360 false "/ foxtrot
+ 'G' 420 false "/ golf
+ 'H' 480 false "/ hotel
+ 'I' 540 false "/ also called india - how misleading
+ 'K' 600 false "/ kilo
+ 'L' 660 false "/ lima - but not there
+ 'M' 720 false "/ mike
+ 'N' -60 false "/ november (but also in other months)
+ 'O' -120 false "/ oscar
+ 'P' -180 false "/ papa (not mama)
+ 'Q' -240 false "/ quebec - really?
+ 'R' -300 false "/ romeo and juliet
+ 'S' -360 false "/ sierra
+ 'T' -420 false "/ tango (& not rumba)
+ 'U' -480 false "/ uniform
+ 'V' -540 false "/ victor
+ 'W' -600 false "/ whiskey (scotch?)
+ 'X' -660 false "/ xray
+ 'Y' -720 false "/ yankee
+
).
!
@@ -1622,7 +1626,8 @@
ch isNil ifTrue:[^ 0].
ch isLetter ifTrue:[
- |table tzName i|
+ |table tzName i minuteOffset|
+
table := self timezoneInfo.
tzName := stream upToElementForWhich:[:ch | ch isLetter not].
@@ -1630,7 +1635,8 @@
i == 0 ifTrue:[
^ nil
].
- offset := (table at:i+1) * 60 * 60
+ minuteOffset := (table at:i+1).
+ offset := minuteOffset * 60
] ifFalse:[
|sign|
@@ -1926,17 +1932,24 @@
(for a correct result, we'd have to care for start-end dates of summer time
of that particular year...)"
- |best myUtcOffset|
+ |myUtcOffset iAmDST bestNonDST|
myUtcOffset := self utcOffset negated.
-
- best := nil.
- self class timezoneInfo pairWiseDo:[:name :offsetInHours |
- |thisUtcOffset|
-
- thisUtcOffset := offsetInHours * 60 * 60.
- thisUtcOffset == myUtcOffset ifTrue:[^ name ].
+ iAmDST := self timeInfo dst ? false.
+
+ bestNonDST := nil.
+ self class timezoneInfo inGroupsOf:3 do:[:name :offsetInMinutes :isDST|
+ |thisUtcOffset|
+
+ thisUtcOffset := offsetInMinutes * 60.
+ thisUtcOffset = myUtcOffset ifTrue:[
+ isDST == iAmDST ifTrue:[^ name ].
+ ].
+ bestNonDST := name.
].
+ bestNonDST notNil ifTrue:[^ bestNonDST].
+
+ "/ nothing found - construct a standard offset string
^ ((self utcOffset > 0) ifTrue:['+'] ifFalse:['-'])
, ((myUtcOffset abs // 60) printStringLeftPaddedTo:2 with:$0)
, ((myUtcOffset abs \\ 60) printStringLeftPaddedTo:2 with:$0)
@@ -1945,10 +1958,11 @@
Timestamp now timeZoneName
UtcTimestamp now timeZoneName
+ (Timestamp now asTZTimestampInZone:'MEZ') timeZoneName - will find international name
(Timestamp now asTZTimestampInZone:'EST') timeZoneName
- (Timestamp now asTZTimestampInZone:'IDLE') timeZoneName
- (Timestamp now asTZTimestampInZone:'BRST') timeZoneName
- (Timestamp now asTZTimestampInZone:'MYT') timeZoneName
+ (Timestamp now asTZTimestampInZone:'IDLE') timeZoneName - sorry - will find 'NZST'
+ (Timestamp now asTZTimestampInZone:'BRST') timeZoneName - sorry: will find military 'O'
+ (Timestamp now asTZTimestampInZone:'MYT') timeZoneName - will find hongkong; same timezone
"
!
@@ -3036,6 +3050,7 @@
"
! !
+
!Timestamp methodsFor:'testing'!
isLocalTimestamp
--- a/WeakArray.st Wed Apr 20 20:11:13 2016 +0100
+++ b/WeakArray.st Thu Apr 21 07:59:19 2016 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1991 by Claus Gittinger
All Rights Reserved
@@ -270,7 +272,7 @@
^ self at:index
!
-at:index ifInvalid:exeptionalValue
+at:index ifInvalid:exceptionalValue
"return the indexed instance variable with index, anInteger,
but only if still valid; otherwise return the value from exceptionalValue"
@@ -278,7 +280,7 @@
el := self basicAt:index.
el class == SmallInteger ifTrue:[
- ^ exeptionalValue value
+ ^ exceptionalValue value
].
^ el
!