eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'ByteArray':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: ByteArray


Inheritance:

   Object
   |
   +--Collection
      |
      +--SequenceableCollection
         |
         +--ArrayedCollection
            |
            +--UninterpretedBytes
               |
               +--ByteArray
                  |
                  +--ImmutableByteArray
                  |
                  +--SignedByteArray
                  |
                  +--UUID

Package:
stx:libbasic
Category:
Collections-Arrayed
Version:
rev: 1.324 date: 2024/02/24 16:59:57
user: cg
file: ByteArray.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


ByteArrays store unsigned 8 bit integers in the range 0..255.
In contrast to normal arrays (which store pointers to their elements),
byteArrays store the values in a dense & compact way.
ByteArrays can be used to hold the data for bitmaps, images and other bulk data
(instances are returned eg. when reading a binary file or socket).
ByteArrays are also used to store the bytecode-instructions of an
interpreted method and are used as superclass for Strings.

ByteArrays can be used as literals i.e. you can enter ByteArray-constants
as
    #[ element1 element2 .... elementN]

and also use byteArray constants as elements in a constant array, as in:
    #( #[1 1 1] #[2 2 2] #[3 3 3])

Notice that the compilers are configured to create instances of ImmutableByteArray for literals.

If you have to communicate structure-data (in the C-sense) with external
programs/data-bases, see companion classes (Structure, ExternalBytes and ExternalStructure).
It allows the definition of subclasses of ByteArray, which transparently fetch
and store C-structure fields.

Aliased as UInt8Array.

[memory requirements:]
    OBJ-HEADER + size        (rounded up to next multiple of wordsize)

[complexity:]
    see Array

copyright

COPYRIGHT (c) 1989 by Claus Gittinger All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

instance creation
o  uninitializedNew: anInteger
return a new instance of the receiver with uninitialized
(i.e. undefined) contents. The indexed elements have any random
value. However, any named instance variables are still nilled.
For use, when contents will be set anyway shortly after - this
is a bit faster than the regular basicNew:, which clears the bytes.
Of course, it only makes a difference for very big ByteArrays, such
as used for images/bitmaps.

Notice: if you want to port code using uninitializedNew: to another
smalltalk, you have to add an 'uninitializedNew: -> basicNew:'-calling
method to the ByteArray class of the other smalltalk.

queries
o  elementByteSize
for bit-like containers, return the number of bytes stored per element.
Here, 1 is returned

o  isBuiltInClass
return true if this class is known by the run-time-system.
Here, true is returned for myself, false for subclasses.

o  isValidElement: anObject
return true, if instances of me can hold this kind of object

o  literalTokenPrefix

o  maxVal
the minimum value which can be stored in instances of me.
For ByteArrays, this is 255

o  minVal
the minimum value which can be stored in instances of me.
For ByteArrays, this is 0


Instance protocol:

Compatibility-Squeak
o  bitXor: aByteArray
return a new byteArray containing the bitWise-xor of the receiver's and the
argument's bytes

Usage example(s):

     #[0 1 2 3 4] bitXor:#[0 1 2 3 4]
     #[0 1 2 3 4] bitXor:#[0 1 2 3]

Compatibility-VW
o  asByteString
same as asString, for visualworks compatibility

accessing
o  atAllPut: byteValue
replace all elements of the collection by the argument, anObject.
Return the receiver.
Notice: This operation modifies the receiver, NOT a copy;
therefore the change may affect all others referencing the receiver.

Usage example(s):

     (ByteArray new:10)
	atAllPut:10;
	yourself

Usage example(s):

     (ByteArray new:10)
	atAllPut:-1;
	yourself

o  basicAt: index
return the indexed instance variable with index, anInteger
- redefined here to be slighly faster than the default in Object.
Q: is it worth the extra code ?

o  basicAt: index put: value
set the indexed instance variable with index, anInteger to value.
Returns value (sigh).
- redefined here to be slighly faster than the default in Object.
Q: is it worth the extra code ?

o  bitAt: index
return the bit at index (1 based index) as 0 or 1

Usage example(s):

     #[ 1 1 1 1 ] bitAt:9
     #[ 1 1 1 1 ] bitAt:11
     #[ 2 2 2 2 ] bitAt:10

o  bitClearAt: index
clear the bit at index (index starts with 1)

Usage example(s):

     #[0 0 0 0] copy bitClearAt:1
     #[0 0 0 0] copy bitClearAt:7
     #[0 0 0 0] copy bitClearAt:8
     #[0 0 0 0] copy bitClearAt:9

o  bitSetAt: index
set the bit at index (index starts with 1)

Usage example(s):

     #[0 0 0 0] copy bitSetAt:1
     #[0 0 0 0] copy bitSetAt:7
     #[0 0 0 0] copy bitSetAt:8
     #[0 0 0 0] copy bitSetAt:9
     #[0 0 0 0] copy bitSetAt:32
     #[0 0 0 0] copy bitSetAt:33
     #[0 0 0 0] copy bitSetAt:0

Usage example(s):

     #[ 0 0 0 0 ] bitSetAt:1
     #[ 0 0 0 0 ] bitSetAt:4
     #[ 0 0 0 0 ] bitSetAt:8
     #[ 0 0 0 0 ] bitSetAt:9
     #[ 0 0 0 0 ] bitSetAt:10
     #[ 0 0 0 0 ] bitSetAt:11

accessing-bytes
o  byteAt: index
return the byte at index.
For ByteArray, this is the same as basicAt:;
however, for strings or symbols, this returns a numeric byteValue
instead of a character.

o  byteAt: index put: value
set the byte at index. For ByteArray, this is the same as basicAt:put:.
However, for Strings, this expects a byteValue to be stored.

accessing-longs
o  unsignedInt32At: index put: value
set the 4-bytes starting at index from the (unsigned) Integer value.
The value should be in the range 0 to 16rFFFFFFFF
(for negative values, the stored value is not defined).
The value is stored in the machine's natural byte order.
Q: should it store signed values ? (see ByteArray signedDoubleWordAt:put:)

Usage example(s):

     |b|
     b := ByteArray new:4.
     b unsignedInt32At:1 put:16r04030201.
     b inspect

o  unsignedInt32At: index put: value MSB: msb
set the 4-bytes starting at index from the (unsigned) Integer value.
The value must be in the range 0 to 16rFFFFFFFF.
The value is stored MSB-first if msb is true; LSB-first otherwise.
question: should it store signed values ? (see ByteArray signedDoubleWordAt:put:)

Usage example(s):

     |b|
     b := ByteArray new:8.
     b unsignedInt32At:1 put:16r04030201 MSB:true.
     b unsignedInt32At:5 put:16r04030201 MSB:false.
     b inspect

accessing-shorts
o  unsignedInt16At: index
return the 2-bytes starting at index as an (unsigned) Integer.
The value is retrieved in the machine's natural byte order
Notice:
the index is a byte index; thus, this allows for unaligned access to
words on any boundary.
Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)

o  unsignedInt16At: index MSB: msb
return the 2-bytes starting at index as an (unsigned) Integer.
The value is retrieved MSB (high 8 bits at lower index) if msb is true;
LSB-first (i.e. low 8-bits at lower byte index) if it's false.
Notice:
the index is a byte index; thus, this allows for unaligned access to
words on any boundary.
Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)

o  unsignedInt16At: index put: value
set the 2-bytes starting at index from the (unsigned) Integer value.
The stored value must be in the range 0 .. 16rFFFF.
The value is stored in the machine's natural byteorder,
i.e. this method should only be used to fill byteArrays which are
used internally (not passed to other machines).
Notice:
the index is a byte index; thus, this allows for unaligned access to
words on any boundary.
Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)

Usage example(s):

     |b|
     b := ByteArray new:4.
     b unsignedInt16At:1 put:16r0102.
     b unsignedInt16At:3 put:16r0304.
     b inspect

o  unsignedInt16At: index put: value MSB: msb
set the 2-bytes starting at index from the (unsigned) Integer value.
The stored value must be in the range 0 .. 16rFFFF.
The value is stored LSB-first (i.e. the low 8bits are stored at the
lower index) if msb is false, MSB-first otherwise.
Notice:
the index is a byte index; thus, this allows for unaligned access to
words on any boundary.
Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)

Usage example(s):

     |b|
     b := ByteArray new:8.
     b unsignedInt16At:1 put:16r0102 MSB:false.
     b unsignedInt16At:3 put:16r0304 MSB:false.
     b unsignedInt16At:5 put:16r0102 MSB:true.
     b unsignedInt16At:7 put:16r0304 MSB:true.
     b inspect

comparing
o  = aByteArray
Compare the receiver with the argument and return true if the
receiver is equal to the argument (i.e. has the same size and elements).
Otherwise return false.

converting
o  asByteArray
return the receiver as a byteArray

Usage example(s):

     'hello world' asByteArray
     #(1 2 3 4 5 6 7) asByteArray
     #(1 2 256 4 5 6 7) asByteArray

o  asDecodedString: encoding
encoding is either a characterEncoder instance
or an encodingSymbol (such as #utf8)

Usage example(s):

      #[16r41 16r42 16r43] asDecodedString:#utf8
      #[16r41 16r42 16r43] asDecodedString:(CharacterEncoder encoderFor:#utf8)
      #[195 164 195 182 195 188] asDecodedString:#utf8
      #[195 164 195 182 195 188] asDecodedString:'utf-8'
      #[195 164 195 182 195 188] asDecodedString:(CharacterEncoder encoderFor:#utf8)

o  asImmutableByteArray
return a write-protected copy of myself

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  asImmutableCollection
return a write-protected copy of myself

Usage example(s):

	(#[1 2 3], #[11 12 13]) asImmutableCollection

o  asInteger
convert myself to an unsigned integer - the first byte is most significant.
This is also in Squeak.

Usage example(s):

	#[ 2 ] asInteger hexPrintString
	#[ 16r1 16r2 ] asInteger hexPrintString
	#[4 0 0 0 0 0 0 0] asInteger hexPrintString

o  asIntegerMSB: isMSBFirst
convert myself to an unsigned integer.
If isMSBFirst, the first byte is most significant otherwise least significant.
This is also in Squeak.

Usage example(s):

	(#[ 2 ] asIntegerMSB:true) hexPrintString
	(#[ 16r1 16r2 ] asIntegerMSB:true) hexPrintString
	(#[ 16r1 16r2 ] asIntegerMSB:false) hexPrintString
	(#[4 0 0 0 0 0 0 0 0 0 0 0] asIntegerMSB:true) hexPrintString

o  asPackedString
ST-80 compatibility: encode the receiver into an ascii String
with 6bits encoded per character. Each group of 6 bits is encoded
as a corresponding character (32+value) and the resulting string
is returned. The resulting string is always a multiple of 4 (since
24 is the lcm of 6 and 8) and the number of remaining characters is
encoded in the last character.
ST-80 uses this encoding for Images...
This is a base64 encoding, very similar (but not equal) to the algorithm used in RFC1421.
PS: I don't like it ;-)
See also: fromPackedString: - the reverse operation

Usage example(s):

     #[ 16r00 16r01 16r02 16r04 16r08 16r10 16r20 16r40 16r80 ] asPackedString

o  asSignedByteArray
return the receiver as a signed byteArray.
elements > 127 are converted to negative numbers.

Usage example(s):

     'hello world' asSignedByteArray
     #[1 2 3 4 5 6 7] asSignedByteArray
     #[1 2 129 4 5 6 7 255] asSignedByteArray

o  asString
speed up string conversions

Usage example(s):

      #[16r41 16r42 16r43] asString
      #[16r41 16r42 16r43] asImmutableByteArray asString

o  beImmutable
make myself write-protected

o  beSigned
destructively make myself signed.
elements > 127 are converted to negative numbers.
WARNING: this changes the receiver itself
- use this only for initialization of new instances

Usage example(s):

     #[ 1 2 3 128 255 ] copy beSigned
     #[ 1 2 3 128 255 ] beImmutable beSigned

o  beUnsigned
that's what I am (but I don't know if this is true for subclasses).

Usage example(s):

     #[ 1 2 3 128 255 ] copy beUnsigned

o  decodeAsLiteralArray
given a literalEncoding in the receiver,
create & return the corresponding object.
The inverse operation to #literalArrayEncoding.

o  literalArrayEncoding
encode myself as an array literal, from which a copy of the receiver
can be reconstructed with #decodeAsLiteralArray.

Usage example(s):

     #[1 2 3] literalArrayEncoding

copying
o  copy
redefined for a bit more speed

o  copyFrom: start to: stop
return the subcollection starting at index start, anInteger and ending
at stop, anInteger.
- reimplemented here for speed

Usage example(s):

     #[1 2 3 4 5 6 7 8 9 10] copyFrom:1 to:10
     #[1 2 3 4 5 6 7 8 9 10] copyFrom:5 to:7

     #[1 2 3 4 5 6 7 8 9 10] copyFrom:5 to:11
     #[1 2 3 4 5 6 7 8 9 10] copyFrom:0 to:10
     #[1 2 3 4 5 6 7 8 9 10] copyFrom:0 to:9

o  shallowCopy
redefined for a bit more speed

o  symbolFrom: start to: stop
make a symbol from the characters of the subcollection starting
at index start, anInteger and ending at stop, anInteger.
This saves us garbage and character copying.

Usage example(s):

     'abcdefghijklmnop' symbolFrom:1 to:3
     'abcdefghijklmnop' symbolFrom:3 to:16
     'abcdefghijklmnop' symbolFrom:3 to:17

filling & replacing
o  from: start to: stop put: aNumber
fill part of the receiver with aNumber.
- reimplemented here for speed

Usage example(s):

     (ByteArray new:10) from:1 to:10 put:1
     (ByteArray new:20) from:10 to:20 put:1
     (ByteArray new:20) from:1 to:10 put:1

image manipulation support
o  bitAndBytesFrom: dstStart to: dstEnd with: sourceBytes startingAt: sourceStart
replace bytes in the receiver with the result of a bitAnd operation.
Warning: this is a destructive operation - elements in the receiver are overwritten.

Usage example(s):

     #[1 2 3 4 5 6 7 8]
	bitAndBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1
     #[1 2 3 4 5 6 7 8]
	bitAndBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1

o  bitBlitBytesFrom: dstStart to: dstEnd with: sourceBytes startingAt: sourceStart rule: ruleSymbol
perform a special case of a bitBlit operation.
Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result
of some logical operation, as specified by the ruleSymbol.
SourceBytes (that may also be s String) are fetched starting at sourceOffset.
Valid rule symbols are:
#copy - trivial; same as replaceBytesFrom:to:with:startingAt:
#copyNot - byte[dI] = (srcByte[sI]) bitInvert
#bitXor: - xoring; byte[dI] = byte[dI] bitXor:(srcByte[sI])
#bitXorNot: - xorNot; byte[dI] = byte[dI] bitXor:(srcByte[sI]) bitInvert
#bitAnd: - anding; byte[dI] = byte[dI] bitAnd:(srcByte[sI])
#bitAndNot: - andNot; byte[dI] = byte[dI] bitAnd:(srcByte[sI]) bitInvert
#bitOr: - oring; byte[dI] = byte[dI] bitOr:(srcByte[sI])
#bitOrNot: - orNot; byte[dI] = byte[dI] bitOr:(srcByte[sI]) bitInvert
#+ - adding; byte[dI] = (byte[dI] + (srcByte[sI])) mod: 256
#- - subtract; byte[dI] = (byte[dI] - (srcByte[sI])) mod: 256
Warning: this is a destructive operation - elements in the receiver are overwritten.

Usage example(s):

     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#bitAnd:
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+
     #[255 0 0 0 0 0 0 0]
	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#+
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#+
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#copyNot

     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 with:(1 to:8) startingAt:1 rule:#+

     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+

     |b1 b2|
     b1 := ByteArray new:100000 withAll:3.
     b2 := ByteArray new:100000 withAll:2.
     Time millisecondsToRun:[
	100000 timesRepeat:[
	    b1 bitBlitBytesFrom:1 to:100000 with:b2 startingAt:1 rule:#bitAnd:.
	]
    ].
    without INT-loop;  with INT-loop
    1420 1436 1421 ->  786 785 793

o  bitBlitBytesFrom: dstStart to: dstEnd withConstant: sourceByte rule: ruleSymbol
perform a special case of an aligned bitBlit operation.
Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result
of some logical operation, as specified by the ruleSymbol.
Valid rule symbols are:
#copy - trivial; same as from:to:put:
#bitXor: - xoring; byte[dI] = byte[dI] bitXor:sourceConst
#bitAnd: - anding; byte[dI] = byte[dI] bitAnd:sourceConst
#bitOr: - oring; byte[dI] = byte[dI] bitOr:sourceConst
#+ - adding; byte[dI] = (byte[dI] + sourceConst) mod: 256
#- - subtract; byte[dI] = (byte[dI] - sourceConst) mod: 256
Warning: this is a destructive operation - elements in the receiver are overwritten.

Usage example(s):

     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:3 withConstant:1 rule:#bitXor:
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitXor:
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitAnd:
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
     #[255 0 0 0 0 0 0 0]
	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:4 withConstant:1 rule:#+
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:4 withConstant:1 rule:#-
     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:4 withConstant:1 rule:#copyNot

     #[1 2 3 4 5 6 7 8]
	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+

o  bitOrBytesFrom: dstStart to: dstEnd with: sourceBytes startingAt: sourceStart
replace bytes in the receiver with the result of a bitOr operation.
Warning: this is a destructive operation - elements in the receiver are overwritten.

Usage example(s):

     #[1 2 3 4 5 6 7 8]
	bitOrBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1
     #[1 2 3 4 5 6 7 8]
	bitOrBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1

o  bitXorBytesFrom: dstStart to: dstEnd with: sourceBytes startingAt: sourceStart
replace bytes in the receiver with the result of an bitXor operation.
Warning: this is a destructive operation - elements in the receiver are overwritten.

Usage example(s):

     #[1 2 3 4 5 6 7 8]
	bitXorBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1
     #[1 2 3 4 5 6 7 8]
	bitXorBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1
     #[1 2 3 4 5 6 7 8]
	bitXorBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1

o  compressPixels: nBitsPerPixel width: width height: height into: aByteArray mapping: aMapByteArray
given the receiver with 8-bit pixels, compress them into aByteArray
with nBitsPerPixel-depth pixels. The width/height-arguments are needed
to allow for any padding. On the fly, the source bytes are translated
using aMapByteArray (if non-nil).
Notice that smalltalk indexing begins at 1; thus the map-index for a byte
value of n is found in map at:(n + 1).
Output bits are filled left-to right, i.e. the first byte in the input
corresponds to the high bit(s) if the first byte in the input.
This method can be used to convert 8-bit image data to mono, 2-bit and 4-bit
bitmaps.
It can also be used to compress byte-arrays into bitArrays.

Usage example(s):

     |inBits outBits|

     inBits := #[0 0 0 0 1 1 1 1
		 0 0 1 1 0 0 1 1
		 0 1 0 1 0 1 0 1
		 1 1 1 1 0 0 0 0].
     outBits := ByteArray new:4.
     inBits compressPixels:1 width:8 height:4
		    into:outBits mapping:nil.
     outBits inspect

Usage example(s):

     |inBits outBits map|

     inBits := #[176 176 176 176 99 99 99 99 176 176 99 99 176 99 176 99].
     map := ByteArray new:256.
     map at:176+1 put:1.

     outBits := ByteArray new:2.
     inBits compressPixels:1 width:16 height:1
		    into:outBits mapping:map.
     outBits inspect

Usage example(s):

     |inBits outBits map|

     inBits := #[176 176 176 176 99 99 99 99 176 176 99 99 176 99 176 99].
     map := ByteArray new:256.
     map atAll:(128+1 to:255+1) put:1.

     outBits := ByteArray new:2.
     inBits compressPixels:1 width:16 height:1
		    into:outBits mapping:map.
     outBits inspect

o  expandPixels: nBitsPerPixel width: width height: height into: aByteArray mapping: aMapByteArray
given the receiver with nBitsPerPixel-depth pixels, expand them into
aByteArray with 8-bit pixels. The width/height-arguments are needed
to skip any padded src-bits. On the fly, the destination pixels
are translated using aMapByteArray (if non-nil).
Input bits are read left-to right, i.e. the first byte in the output
corresponds to the high bit(s) in the inputs first byte.
This is used to display mono, 2-bit and 4-bit bitmaps on grey-scale/color
machines. With nBitsPerPixel==8, this is a translate operation.
Notice that smalltalk indexing begins at 1; thus the map-index for a byte
value of n is found in map at:(n + 1).
It can also be used to expand bit-arrays into byteArrays.
This method is specialized for ByteArray arguments - it will not handle
anything else.

Usage example(s):

     |inBits outBits|

     inBits := #[2r11110000
		 2r11001100
		 2r01010101
		 2r00001111].
     outBits := ByteArray new:(8*4).
     inBits expandPixels:1 width:8 height:4
		    into:outBits mapping:nil.
     outBits inspect

Usage example(s):

     |inBits outBits|

     inBits := #[2r11110000 2r11001100].
     outBits := ByteArray new:16.
     inBits expandPixels:1 width:16 height:1
		    into:outBits mapping:#[99 176].
     outBits inspect

Usage example(s):

     |inBits outBits|

     inBits := #[ 16r12 16r34 16r56 16r78 16r9A 16rBC 16rDE 16rF0 ].
     outBits := ByteArray new:(inBits size * 2).
     inBits expandPixels:4 width:outBits size height:1 into:outBits mapping:nil.
     outBits inspect

o  invert
invert all bytes inplace - used with image manipulations
written as a primitive for speed.
Warning: destructive; modifies the receiver - not a copy.
Q: is this really needed ?

Usage example(s):

     #[1 2 3 4 5 6 7 8 9 10] copy invert
     #[1 2 3 4 5 6 7 8 9 10] copy
	bitBlitBytesFrom:1 to:10 withConstant:16rFF rule:#bitXor:

     |l|
     l := ByteArray fromHexString:'0102030405060708090a0b0c0d0e0f1112131415161718191a1b1c1d1e1f'.
     Time millisecondsToRun:[
	1000000 timesRepeat:[ l invert ].
     ]

o  reverse
reverse the order of my elements inplace -
WARNING: this is a destructive operation, which modifies the receiver.
Please use reversed (with a 'd' at the end) for a functional version.
Written as a primitive for speed on image manipulations (mirror)

Usage example(s):

     #[1 2 3 4 5] copy reverse
     #[] copy reverse
     #[1] copy reverse
     #[1 2] copy reverse
     #[1 2 3] copy reverse
     #[1 2 3 4] copy reverse
     #[1 2 3 4 5] copy reverse
     #[1 2 3 4 5 6] copy reverse
     #[1 2 3 4 5 6 7] copy reverse
     #[1 2 3 4 5 6 7 8] copy reverse
     #[1 2 3 4 5 6 7 8] copy reverseFrom:2 to:5
     #[1 2 3 4 5 6 7 8 9] copy reverse
     #[1 2 3 4 5 6 7 8 9 10] copy reverse
     #[1 2 3 4 5 6 7 8 9 10 11 12] copy reverse
     #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] copy reverse
     #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] copy reverse
     (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
	]
     ].

     Time millisecondsToRun:[
	10000000 timesRepeat:[
	    #[1 2 3 4 5 6 7 8] reverse
	]
     ]

     |b|
     b := (0 to:255) asByteArray.
     Time millisecondsToRun:[
	10000000 timesRepeat:[
	    b reverse
	]
     ]

o  reverseBits
reverse the bit order in each of my elements inplace -
WARNING: this is a destructive operation, which modifies the receiver.
Written as a primitive for speed on image manipulations (mirror)

Usage example(s):

     #[1 2 3 4 5] copy reverseBits
     #[] copy reverseBits
     #[1] copy reverseBits
     #[1 2] copy reverseBits
     #[1 2 3] copy reverseBits
     #[1 2 3 4] copy reverseBits
     #[1 2 3 4 5] copy reverseBits
     #[1 2 3 4 5 6] copy reverseBits
     #[1 2 3 4 5 6 7] copy reverseBits
     #[1 2 3 4 5 6 7 8] copy reverseBits
     #[1 2 3 4 5 6 7 8] copy reverseBitsFrom:2 to:5
     #[1 2 3 4 5 6 7 8 9] copy reverseBits
     #[1 2 3 4 5 6 7 8 9 10] copy reverseBits
     #[1 2 3 4 5 6 7 8 9 10 11 12] copy reverseBits
     #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] copy reverseBits
     #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] copy reverseBits
     (0 to:255) asByteArray reverseBits
     self assert:((0 to:255) asByteArray reverseBits) = ((0 to:255) asByteArray collect:#bitReversed8)

     |b|
     b := (0 to:255) asByteArray.
     Time millisecondsToRun:[
	1000000 timesRepeat:[
	    b reverseBits
	]
     ]
	basicAt:  2750 2734
	at:       3515 3516
	primitive: 844 781
	primitive LSB: 734

o  swap: i1 with: i2
swap the bytes at i1 and i2

inspecting
o  inspectorExtraAttributes
( an extension from the stx:libtool package )
extra (pseudo instvar) entries to be shown in an inspector.

o  inspectorValueStringInListFor: anInspector
( an extension from the stx:libtool package )
returns a string to be shown in the inspector's list

printing & storing
o  displayOn: aGCOrStream
return a printed representation of the receiver for displaying

o  printOn: aStream
append a printed representation to aStream

Usage example(s):

     #[1 2 3 4 5] printOn:Transcript


     #[1 2 3 4 5] storeString
     #[1 2 3 4 5] displayString
     #[1 2 3 4 5] printString

o  printOn: aStream base: radix
append a printed representation to aStream in the given number base.

Usage example(s):

     #[1 2 3 4 5] printOn:Transcript base:2
     'Hello World' printOn:Transcript base:2

     #[1 2 3 4 5] storeString
     #[1 2 3 4 5] displayString
     #[1 2 3 4 5] printString

o  printOn: aStream base: radix showRadix: showRadix
append a printed representation to aStream in the given number base.

Usage example(s):

     #[1 2 3 4 5] printOn:Transcript base:2
     'Hello World' asByteArray printOn:Transcript base:2 showRadix:false

     #[1 2 3 4 5] storeString
     #[1 2 3 4 5] displayString
     #[1 2 3 4 5] printString

o  printOn: aStream base: radix showRadix: showRadix wrapAfter: colCntOrNil
append a printed representation to aStream in the given number base.

Usage example(s):

     #[1 2 3 4 5] printOn:Transcript base:2
     (1 to:255) asByteArray printOn:Transcript base:16 showRadix:false wrapAfter:16
     'Hello World' printOn:Transcript base:2

     #[1 2 3 4 5] storeString
     #[1 2 3 4 5] displayString
     #[1 2 3 4 5] printString

o  storeAsArrayElementOn: aStream
Store as element of an array. Omit the leading '#'

o  storeOn: aStream
append a printed representation from which the receiver can be
reconstructed to aStream. (reimplemented to make it look better)

Usage example(s):

     #[1 2 3 4 5] storeOn:Transcript

     #[1 2 3 4 5] storeString
     #[1 2 3 4 5] displayString
     #[1 2 3 4 5] printString

queries
o  characterSize
answer the size in bits of my largest character (actually only 7, 8, 16 or 32).
Needed in case someone writes bytes to a CharacterWriteStream (comanche response)

o  containsNon7BitAscii
return true, if any byte in the receiver has the 7th bit on.
This may look as a too specific operation to be put here,
put it is very helpful for UTF8 string reading (Java class reader),
to quickly determine, if UTF8 decoding is needed or not.
As most strings in a class file are in fact only containing 7bit ascii,
this should speedup class file reading considerably

Usage example(s):

     #[1 2 3 1 2 3 1 2 127 ] containsNon7BitAscii
     #[1 2 3 1 2 3 1 2 250 251 250 251 255] containsNon7BitAscii

o  containsNon8BitElements
return true, if one of my elements is larger than a single byte.
Per definition not.

o  isEmpty
return true if the receiver is empty (i.e. if size == 0)
Redefined here for performance

o  isEmptyOrNil
return true if the receiver is empty (i.e. if size == 0)
Redefined here for performance

o  max
return the maximum value in the receiver -
redefined to speedup image processing and sound-player
(which need a fast method for this on byteArrays)

Usage example(s):

     #[1 2 3 1 2 3 1 2 19] max
     #[] max

o  notEmpty
return true if the receiver is not empty (i.e. if size ~~ 0)
Redefined here for performance

o  notEmptyOrNil
return true if the receiver is not empty (i.e. if size ~~ 0)
Redefined here for performance

o  startsWith: aByteOrByteArray
return true, if the receiver starts with aByteOrByteArray.
If the argument is empty, true is returned.
Notice, that this is similar to, but slightly different from VW's and Squeak's beginsWith:,
which are both inconsistent w.r.t. an empty argument.

Usage example(s):

     #[1 2 3 4 5 6 7 8 9 10] startsWith:#[ 1 2 3 4 5]
     #[1 2 3 4] startsWith:#[ 1 3 4 5]
     #[1 2 3 4 5 6 7 8 9 10] startsWith:#[ 0 1 2 3 4 5]
     #[1 2 3 4 5 6 7 8 9 10] startsWith:#(1 2 3 4 5)
     #[1 2 3 4 5 6 7 8 9 10] startsWith:1
     #[1 2 3 4 5 6 7 8 9 10] startsWith:2

o  usageCounts
return an array filled with value-counts -
This is needed in the bitmap/image classes to get info on color usage.
(i.e. to build up a histogram of color usage within an image).

Usage example(s):

     #[1 2 3 1 2 3 1 2 250 251 250 251 255] usageCounts

o  usedValues
return a new ByteArray with all used values (actually a kind of Set);
This is needed specially in the bitmap/Imageclasses to find used colors
of an image.

Usage example(s):

     #[1 2 3 1 2 3 1 2 3 1 2 3 4 5 6 4 5 6] usedValues
     (ByteArray new:100000 withAll:0) usedValues

Usage example(s):

     |b|
     b := ByteArray new:100000 withAll:0.
     Time microsecondsToRun:[
	b usedValues
     ]
     47 46 53 47 39 char loop
     54 54 55       INT loop (!)

o  utf8DecodedSize
return the number of characters needed when this string is
decoded from UTF-8.

Usage example(s):

     'hello world' asByteArray utf8DecodedSize
     'ä' utf8Encoded asByteArray utf8DecodedSize
     'äΣΔΨӕἤῴ' utf8Encoded asByteArray utf8DecodedSize

searching
o  identityIndexOf: aByte
return the index of the first occurrences of the argument, aByte
in the receiver or 0 if not found - reimplemented here for speed.

o  identityIndexOf: aByte startingAt: index
return the index of the first occurrences of the argument, aByte
in the receiver or 0 if not found - reimplemented here for speed.

o  includesAny: aCollection
return true, if the receiver includes any of the bytes in the
argument, aCollection.
- redefined for speed if the argument is a ByteArray; especially optimized,
if the searched collection has less than 6 characters.
Code copied from String and adapted.

Usage example(s):

     'hello world' asByteArray includesAny:'abcd' asByteArray
     'hello world' asByteArray includesAny:'xyz' asByteArray
     'hello world' asByteArray includesAny:'xz' asByteArray
     'hello world' asByteArray includesAny:'od' asByteArray
     'hello world' asByteArray includesAny:'xd' asByteArray
     'hello world' asByteArray includesAny:'dx' asByteArray
     'hello world' asByteArray includesAny:'d' asByteArray
     'hello world' asByteArray includesAny:'x' asByteArray
     'hello world' asByteArray includesAny:#(1 2)
     #[1 2 3 4 5 6 7] includesAny:#(1 2)

     |s|
     s := ByteArray new:1000 withAll:42.
     TimeDuration toRun:[
	1000000 timesRepeat:[
	    s includesAny:#[1 2]
	]
     ].

     |s|
     s := ByteArray new:2000 withAll:42.
     TimeDuration toRun:[
	1000000 timesRepeat:[
	    s includesAny:#[1 2]
	]
     ].

     |s|
     s := 'hello world' asByteArray.
     TimeDuration toRun:[
	1000000 timesRepeat:[
	    s includesAny:#[1 2]
	]
     ].

o  indexOf: aByte startingAt: start
return the index of the first occurrence of the argument, aByte
in the receiver starting at start, anInteger; return 0 if not found.
- reimplemented here for speed.
This is an adaption of the code in String.

Usage example(s):

     #[1 2 3 4 5 6 7 8 9 0 1 2 3 4 5] indexOf:0 startingAt:1

testing
o  isByteArray
return true, if the receiver is some kind of bytearray;
true is returned here - the method is redefined from Object.

o  isIntegerArray
return true if the receiver has integer elements.
These are Byte- and Integer arrays; both signed and unsigned

o  isLiteral
return true, if the receiver can be used as a literal constant in ST syntax
(i.e. can be used in constant arrays)

o  isSingleByteCollection
(comment from inherited method)
return true, if the receiver has access methods for bytes;
i.e. #at: and #at:put: accesses a byte and are equivalent to #byteAt: and byteAt:put:
and #replaceFrom:to: is equivalent to #replaceBytesFrom:to:.
This is different from 'self class isBytes',
true is returned here - the method is redefined from Object.



ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 27 Jul 2024 13:41:50 GMT