ByteArray.st
changeset 8908 68017b13590b
parent 8901 824a89d0b5c7
child 8913 b9498d27a554
equal deleted inserted replaced
8907:9575741eeda7 8908:68017b13590b
    83 
    83 
    84     "Created: / 5.3.1998 / 15:57:52 / stefan"
    84     "Created: / 5.3.1998 / 15:57:52 / stefan"
    85 !
    85 !
    86 
    86 
    87 fromHexString:aString
    87 fromHexString:aString
    88     "Dolphin compatibility: 
    88     "Dolphin compatibility:
    89      decode a byteArray from a hex string (as generated by hexPrintOn:)"
    89      decode a byteArray from a hex string (as generated by hexPrintOn:)"
    90 
    90 
    91     |sz       "{ Class: SmallInteger }"
    91     |sz       "{ Class: SmallInteger }"
    92      chars s bytes|
    92      chars s bytes|
    93 
    93 
    96     sz odd ifTrue:[self error:'invalid hex string (odd size)'.].
    96     sz odd ifTrue:[self error:'invalid hex string (odd size)'.].
    97 
    97 
    98     bytes := self new:(sz // 2).
    98     bytes := self new:(sz // 2).
    99     s := aString readStream.
    99     s := aString readStream.
   100     1 to:sz // 2 do:[:idx |
   100     1 to:sz // 2 do:[:idx |
   101         chars := s next:2.
   101 	chars := s next:2.
   102         bytes at:idx put:(Integer readFrom:chars radix:16).
   102 	bytes at:idx put:(Integer readFrom:chars radix:16).
   103     ].
   103     ].
   104     ^ bytes
   104     ^ bytes
   105 
   105 
   106     "
   106     "
   107      ByteArray fromHexString:'1234FEFF' 
   107      ByteArray fromHexString:'1234FEFF'
   108     "
   108     "
   109     "
   109     "
   110      |s|
   110      |s|
   111      s := String streamContents:[:s | #[1 2 3] hexPrintOn:s].
   111      s := String streamContents:[:s | #[1 2 3] hexPrintOn:s].
   112      ByteArray fromHexString:s      
   112      ByteArray fromHexString:s
   113     "
   113     "
   114 
   114 
   115     "Modified: / 6.3.1997 / 15:28:52 / cg"
   115     "Modified: / 6.3.1997 / 15:28:52 / cg"
   116 !
   116 !
   117 
   117 
   118 fromPackedString:aString
   118 fromPackedString:aString
   119     "ST-80 compatibility: decode a byteArray from a packed string in which
   119     "ST-80 compatibility: decode a byteArray from a packed string in which
   120      6bits are encoded per character. The argument, aString must be a multiple 
   120      6bits are encoded per character. The argument, aString must be a multiple
   121      of 4 in size (since 24 is the lcm of 6 and 8). This is somewhat like
   121      of 4 in size (since 24 is the lcm of 6 and 8). This is somewhat like
   122      the radix-encoding used in good old PDP11 times ;-)
   122      the radix-encoding used in good old PDP11 times ;-)
   123      ST-80 uses this encoding for Images ...
   123      ST-80 uses this encoding for Images ...
   124      This is very similar (but not equal) to the algorithm used in RFC1421.
   124      This is very similar (but not equal) to the algorithm used in RFC1421.
   125      PS: It took a while to figure that one out ... I dont like it ;-)"
   125      PS: It took a while to figure that one out ... I dont like it ;-)"
   142     "the size modulo 3 is encoded in the last character, if its in the
   142     "the size modulo 3 is encoded in the last character, if its in the
   143      range 97 .. otherwise, its exact."
   143      range 97 .. otherwise, its exact."
   144 
   144 
   145     lastCharacter := aString last.
   145     lastCharacter := aString last.
   146     lastCharacter codePoint > 96 ifTrue:[
   146     lastCharacter codePoint > 96 ifTrue:[
   147         stop := stop - 3 + lastCharacter codePoint - 96
   147 	stop := stop - 3 + lastCharacter codePoint - 96
   148     ].
   148     ].
   149     bytes := self new:stop.
   149     bytes := self new:stop.
   150 
   150 
   151     index := 1. dstIndex := 1.
   151     index := 1. dstIndex := 1.
   152     [dstIndex <= stop] whileTrue:[
   152     [dstIndex <= stop] whileTrue:[
   153         "/ take 4 characters ...
   153 	"/ take 4 characters ...
   154         "/ allow a line break before each group of 4
   154 	"/ allow a line break before each group of 4
   155         sixBits := (aString at:index) codePoint.
   155 	sixBits := (aString at:index) codePoint.
   156         [sixBits < 32] whileTrue:[
   156 	[sixBits < 32] whileTrue:[
   157             index := index + 1.
   157 	    index := index + 1.
   158             sixBits := (aString at:index) codePoint.
   158 	    sixBits := (aString at:index) codePoint.
   159         ].
   159 	].
   160         sixBits := sixBits bitAnd:16r3F.
   160 	sixBits := sixBits bitAnd:16r3F.
   161         n := sixBits.
   161 	n := sixBits.
   162         
   162 
   163         sixBits := (aString at:index+1) codePoint.
   163 	sixBits := (aString at:index+1) codePoint.
   164         sixBits := sixBits bitAnd:16r3F.
   164 	sixBits := sixBits bitAnd:16r3F.
   165         n := (n bitShift:6) + sixBits.
   165 	n := (n bitShift:6) + sixBits.
   166 
   166 
   167         sixBits := (aString at:index+2) codePoint.
   167 	sixBits := (aString at:index+2) codePoint.
   168         sixBits := sixBits bitAnd:16r3F.
   168 	sixBits := sixBits bitAnd:16r3F.
   169         n := (n bitShift:6) + sixBits.
   169 	n := (n bitShift:6) + sixBits.
   170 
   170 
   171         sixBits := (aString at:index+3) codePoint.
   171 	sixBits := (aString at:index+3) codePoint.
   172         sixBits := sixBits bitAnd:16r3F.
   172 	sixBits := sixBits bitAnd:16r3F.
   173         n := (n bitShift:6) + sixBits.
   173 	n := (n bitShift:6) + sixBits.
   174 
   174 
   175         index := index + 4.
   175 	index := index + 4.
   176 
   176 
   177         "/ now have 24 bits in n
   177 	"/ now have 24 bits in n
   178 
   178 
   179         bytes at:dstIndex put:(n bitShift:-16).
   179 	bytes at:dstIndex put:(n bitShift:-16).
   180 
   180 
   181         dstIndex < stop ifTrue:[
   181 	dstIndex < stop ifTrue:[
   182             bytes at:dstIndex+1 put:((n bitShift:-8) bitAnd:16rFF).
   182 	    bytes at:dstIndex+1 put:((n bitShift:-8) bitAnd:16rFF).
   183             dstIndex+2 <= stop ifTrue:[
   183 	    dstIndex+2 <= stop ifTrue:[
   184                 bytes at:dstIndex+2 put:(n bitAnd:16rFF).
   184 		bytes at:dstIndex+2 put:(n bitAnd:16rFF).
   185             ]
   185 	    ]
   186         ].
   186 	].
   187         dstIndex := dstIndex + 3.
   187 	dstIndex := dstIndex + 3.
   188     ].
   188     ].
   189     ^ bytes
   189     ^ bytes
   190 
   190 
   191     "
   191     "
   192      ByteArray fromPackedString:(#[1 1 1 1] asPackedString) 
   192      ByteArray fromPackedString:(#[1 1 1 1] asPackedString)
   193      ByteArray fromPackedString:(#[1 1 1 1 1] asPackedString) 
   193      ByteArray fromPackedString:(#[1 1 1 1 1] asPackedString)
   194      ByteArray fromPackedString:(#[1 1 1 1 1 1] asPackedString) 
   194      ByteArray fromPackedString:(#[1 1 1 1 1 1] asPackedString)
   195      ByteArray fromPackedString:(#[1 1 1 1 1 1 1] asPackedString) 
   195      ByteArray fromPackedString:(#[1 1 1 1 1 1 1] asPackedString)
   196      ByteArray fromPackedString:(#[1 1 1 1 1 1 1 1] asPackedString) 
   196      ByteArray fromPackedString:(#[1 1 1 1 1 1 1 1] asPackedString)
   197 
   197 
   198     "
   198     "
   199 
   199 
   200     "Modified: / 6.3.1997 / 15:28:52 / cg"
   200     "Modified: / 6.3.1997 / 15:28:52 / cg"
   201     "Modified: / 18.12.1997 / 17:17:11 / stefan"
   201     "Modified: / 18.12.1997 / 17:17:11 / stefan"
   202 !
   202 !
   203 
   203 
   204 uninitializedNew:anInteger
   204 uninitializedNew:anInteger
   205     "return a new instance of the receiver with uninitialized
   205     "return a new instance of the receiver with uninitialized
   206      (i.e. undefined) contents. The indexed elements have any random
   206      (i.e. undefined) contents. The indexed elements have any random
   207      value. However, any named instance variables are still nilled. 
   207      value. However, any named instance variables are still nilled.
   208      For use, when contents will be set anyway shortly after - this
   208      For use, when contents will be set anyway shortly after - this
   209      is a bit faster than the regular basicNew:, which clears the bytes.
   209      is a bit faster than the regular basicNew:, which clears the bytes.
   210      Of course, it only makes a difference for very big ByteArrays, such
   210      Of course, it only makes a difference for very big ByteArrays, such
   211      as used for images/bitmaps.
   211      as used for images/bitmaps.
   212 
   212 
   213      Notice: if you want to port code using uninitializedNew: to another
   213      Notice: if you want to port code using uninitializedNew: to another
   214      smalltalk, you have to add an 'uninitializedNew: -> basicNew:'-calling 
   214      smalltalk, you have to add an 'uninitializedNew: -> basicNew:'-calling
   215      method to the ByteArray class of the other smalltalk."
   215      method to the ByteArray class of the other smalltalk."
   216 
   216 
   217 %{  /* NOCONTEXT */
   217 %{  /* NOCONTEXT */
   218     OBJ newobj;
   218     OBJ newobj;
   219     INT instsize, nInstVars, nindexedinstvars;
   219     INT instsize, nInstVars, nindexedinstvars;
   220     REGISTER OBJ *op;
   220     REGISTER OBJ *op;
   221 
   221 
   222     if (__isSmallInteger(anInteger)) {
   222     if (__isSmallInteger(anInteger)) {
   223         nindexedinstvars = __intVal(anInteger);
   223 	nindexedinstvars = __intVal(anInteger);
   224         if (nindexedinstvars >= 0) {
   224 	if (nindexedinstvars >= 0) {
   225             if (self == ByteArray) {
   225 	    if (self == ByteArray) {
   226                 /*
   226 		/*
   227                  * the most common case
   227 		 * the most common case
   228                  */
   228 		 */
   229                 instsize = OHDR_SIZE + nindexedinstvars;
   229 		instsize = OHDR_SIZE + nindexedinstvars;
   230                 if (__CanDoQuickNew(instsize)) {        /* OBJECT ALLOCATION */
   230 		if (__CanDoQuickNew(instsize)) {        /* OBJECT ALLOCATION */
   231                     __qCheckedNew(newobj, instsize);
   231 		    __qCheckedNew(newobj, instsize);
   232                     __InstPtr(newobj)->o_class = self;
   232 		    __InstPtr(newobj)->o_class = self;
   233                     __qSTORE(newobj, self);
   233 		    __qSTORE(newobj, self);
   234                     RETURN (newobj );
   234 		    RETURN (newobj );
   235                 }
   235 		}
   236             } else {
   236 	    } else {
   237                 /*
   237 		/*
   238                  * Take care for subclasses like TwoByteString
   238 		 * Take care for subclasses like TwoByteString
   239                  */
   239 		 */
   240                 switch (__smallIntegerVal(__ClassInstPtr(self)->c_flags) & ARRAYMASK) {
   240 		switch (__smallIntegerVal(__ClassInstPtr(self)->c_flags) & ARRAYMASK) {
   241                 case BYTEARRAY:
   241 		case BYTEARRAY:
   242                     break;
   242 		    break;
   243             
   243 
   244                 case WORDARRAY:
   244 		case WORDARRAY:
   245                 case SWORDARRAY:
   245 		case SWORDARRAY:
   246                     nindexedinstvars *= 2;
   246 		    nindexedinstvars *= 2;
   247                     break;
   247 		    break;
   248 
   248 
   249                 case LONGARRAY:
   249 		case LONGARRAY:
   250                 case SLONGARRAY:
   250 		case SLONGARRAY:
   251                     nindexedinstvars *= 4;
   251 		    nindexedinstvars *= 4;
   252                     break;
   252 		    break;
   253 
   253 
   254                 default:
   254 		default:
   255                     /* don't know about this array type, delegate to super */
   255 		    /* don't know about this array type, delegate to super */
   256                     goto out;
   256 		    goto out;
   257                 }
   257 		}
   258             }
   258 	    }
   259             nInstVars = __intVal(__ClassInstPtr(self)->c_ninstvars);
   259 	    nInstVars = __intVal(__ClassInstPtr(self)->c_ninstvars);
   260             instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + nindexedinstvars;
   260 	    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars) + nindexedinstvars;
   261             __PROTECT_CONTEXT__
   261 	    __PROTECT_CONTEXT__
   262             __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
   262 	    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
   263             __UNPROTECT_CONTEXT__
   263 	    __UNPROTECT_CONTEXT__
   264             if (newobj != nil) {
   264 	    if (newobj != nil) {
   265                 __InstPtr(newobj)->o_class = self;
   265 		__InstPtr(newobj)->o_class = self;
   266                 __qSTORE(newobj, self);
   266 		__qSTORE(newobj, self);
   267                 if (nInstVars) {
   267 		if (nInstVars) {
   268                     /*
   268 		    /*
   269                      * still have to nil out named instvars ...
   269 		     * still have to nil out named instvars ...
   270                      */
   270 		     */
   271 #if defined(memset4) && defined(FAST_OBJECT_MEMSET4)
   271 #if defined(memset4) && defined(FAST_OBJECT_MEMSET4)
   272                     memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
   272 		    memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
   273 #else
   273 #else
   274 # if defined(FAST_MEMSET) && !defined(NEGATIVE_ADDRESSES)
   274 # if defined(FAST_MEMSET) && !defined(NEGATIVE_ADDRESSES)
   275                     /*
   275 		    /*
   276                      * knowing that nil is 0
   276 		     * knowing that nil is 0
   277                      */
   277 		     */
   278                     memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
   278 		    memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
   279 # else
   279 # else
   280                     op = __InstPtr(newobj)->i_instvars;
   280 		    op = __InstPtr(newobj)->i_instvars;
   281                     while (nInstVars--)
   281 		    while (nInstVars--)
   282                         *op++ = nil;
   282 			*op++ = nil;
   283 # endif
   283 # endif
   284 #endif
   284 #endif
   285                 }
   285 		}
   286                 RETURN ( newobj );
   286 		RETURN ( newobj );
   287             }
   287 	    }
   288         }
   288 	}
   289     }
   289     }
   290 out:;
   290 out:;
   291 %}.
   291 %}.
   292     ^ self basicNew:anInteger
   292     ^ self basicNew:anInteger
   293 !
   293 !
   309 !ByteArray class methodsFor:'binary storage'!
   309 !ByteArray class methodsFor:'binary storage'!
   310 
   310 
   311 binaryDefinitionFrom: stream manager: manager
   311 binaryDefinitionFrom: stream manager: manager
   312     "get a ByteArray from the binary stream.
   312     "get a ByteArray from the binary stream.
   313      ByteArrays are stored as 4-byte size, followed by the bytes.
   313      ByteArrays are stored as 4-byte size, followed by the bytes.
   314      This is only invoked for long bytearrays. 
   314      This is only invoked for long bytearrays.
   315      Short ones are stored with 1byte length."
   315      Short ones are stored with 1byte length."
   316 
   316 
   317     |b len|
   317     |b len|
   318 
   318 
   319     "take care of subclasses ..."
   319     "take care of subclasses ..."
   414 
   414 
   415     "Modified: 19.4.1996 / 11:14:40 / cg"
   415     "Modified: 19.4.1996 / 11:14:40 / cg"
   416 !
   416 !
   417 
   417 
   418 bitAt:index
   418 bitAt:index
   419     "return the bit at index (1 based index)" 
   419     "return the bit at index (1 based index)"
   420 
   420 
   421     |byteIndex bitIndex0 byte|
   421     |byteIndex bitIndex0 byte|
   422 
   422 
   423 %{  /* NOCONTEXT */
   423 %{  /* NOCONTEXT */
   424 
   424 
   427     int nIndex;
   427     int nIndex;
   428     REGISTER OBJ slf;
   428     REGISTER OBJ slf;
   429     REGISTER OBJ cls;
   429     REGISTER OBJ cls;
   430 
   430 
   431     if (__isSmallInteger(index)) {
   431     if (__isSmallInteger(index)) {
   432         indx = __intVal(index) - 1;
   432 	indx = __intVal(index) - 1;
   433         slf = self;
   433 	slf = self;
   434 
   434 
   435         byte = indx / 8;
   435 	byte = indx / 8;
   436         indx = indx % 8;
   436 	indx = indx % 8;
   437 
   437 
   438         if ((cls = __qClass(slf)) != @global(ByteArray)) {
   438 	if ((cls = __qClass(slf)) != @global(ByteArray)) {
   439             if (indx < 0) goto badIndex;
   439 	    if (indx < 0) goto badIndex;
   440             byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   440 	    byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   441         }
   441 	}
   442         nIndex = __byteArraySize(slf);
   442 	nIndex = __byteArraySize(slf);
   443         if ((unsigned)byte < (unsigned)nIndex) {
   443 	if ((unsigned)byte < (unsigned)nIndex) {
   444             RETURN ( __MKSMALLINT((__ByteArrayInstPtr(slf)->ba_element[byte] & (1 << indx)) != 0) );
   444 	    RETURN ( __MKSMALLINT((__ByteArrayInstPtr(slf)->ba_element[byte] & (1 << indx)) != 0) );
   445         }
   445 	}
   446     }
   446     }
   447 badIndex: ;
   447 badIndex: ;
   448 %}.
   448 %}.
   449     byteIndex := ((index-1) // 8) + 1.
   449     byteIndex := ((index-1) // 8) + 1.
   450     bitIndex0 := ((index-1) \\ 8).
   450     bitIndex0 := ((index-1) \\ 8).
   460 
   460 
   461 
   461 
   462 !
   462 !
   463 
   463 
   464 bitClearAt:index
   464 bitClearAt:index
   465     "clear the bit at index (index starts with 1)" 
   465     "clear the bit at index (index starts with 1)"
   466 
   466 
   467     |byteIndex bitIndex0 byte|
   467     |byteIndex bitIndex0 byte|
   468 
   468 
   469 %{  /* NOCONTEXT */
   469 %{  /* NOCONTEXT */
   470 
   470 
   473     int nIndex;
   473     int nIndex;
   474     REGISTER OBJ slf;
   474     REGISTER OBJ slf;
   475     REGISTER OBJ cls;
   475     REGISTER OBJ cls;
   476 
   476 
   477     if (0 /* __isSmallInteger(index) */) {
   477     if (0 /* __isSmallInteger(index) */) {
   478         indx = __intVal(index) - 1;
   478 	indx = __intVal(index) - 1;
   479         slf = self;
   479 	slf = self;
   480 
   480 
   481         byte = indx / 8;
   481 	byte = indx / 8;
   482         indx = indx % 8;
   482 	indx = indx % 8;
   483 
   483 
   484         if ((cls = __qClass(slf)) != @global(ByteArray)) {
   484 	if ((cls = __qClass(slf)) != @global(ByteArray)) {
   485             if (indx < 0) goto badIndex;
   485 	    if (indx < 0) goto badIndex;
   486             byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   486 	    byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   487         }
   487 	}
   488         nIndex = __byteArraySize(slf);
   488 	nIndex = __byteArraySize(slf);
   489         if ((unsigned)byte < (unsigned)nIndex) {
   489 	if ((unsigned)byte < (unsigned)nIndex) {
   490             __ByteArrayInstPtr(slf)->ba_element[byte] &= ~(1 << indx);
   490 	    __ByteArrayInstPtr(slf)->ba_element[byte] &= ~(1 << indx);
   491             RETURN (slf);
   491 	    RETURN (slf);
   492         }
   492 	}
   493     }
   493     }
   494 badIndex: ;
   494 badIndex: ;
   495 %}.
   495 %}.
   496     byteIndex := ((index-1) // 8) + 1.
   496     byteIndex := ((index-1) // 8) + 1.
   497     bitIndex0 := ((index-1) \\ 8).
   497     bitIndex0 := ((index-1) \\ 8).
   498     byte := self at:byteIndex.
   498     byte := self at:byteIndex.
   499     byte := byte bitClear:(1 bitShift:bitIndex0).
   499     byte := byte bitClear:(1 bitShift:bitIndex0).
   500     self at:byteIndex put:byte.
   500     self at:byteIndex put:byte.
   501 
   501 
   502     "
   502     "
   503      #[0 0 0 0] copy bitClearAt:1  
   503      #[0 0 0 0] copy bitClearAt:1
   504      #[0 0 0 0] copy bitClearAt:7  
   504      #[0 0 0 0] copy bitClearAt:7
   505      #[0 0 0 0] copy bitClearAt:8  
   505      #[0 0 0 0] copy bitClearAt:8
   506      #[0 0 0 0] copy bitClearAt:9  
   506      #[0 0 0 0] copy bitClearAt:9
   507     "
   507     "
   508    "
   508    "
   509      #[ 0 0 0 0 ] bitSetAt:1  
   509      #[ 0 0 0 0 ] bitSetAt:1
   510      #[ 0 0 0 0 ] bitSetAt:4  
   510      #[ 0 0 0 0 ] bitSetAt:4
   511      #[ 0 0 0 0 ] bitSetAt:8  
   511      #[ 0 0 0 0 ] bitSetAt:8
   512      #[ 0 0 0 0 ] bitSetAt:9  
   512      #[ 0 0 0 0 ] bitSetAt:9
   513      #[ 0 0 0 0 ] bitSetAt:10 
   513      #[ 0 0 0 0 ] bitSetAt:10
   514      #[ 0 0 0 0 ] bitSetAt:11 
   514      #[ 0 0 0 0 ] bitSetAt:11
   515    "
   515    "
   516 
   516 
   517 
   517 
   518 
   518 
   519 !
   519 !
   520 
   520 
   521 bitSetAt:index
   521 bitSetAt:index
   522     "set the bit at index (index starts with 1)" 
   522     "set the bit at index (index starts with 1)"
   523 
   523 
   524     |byteIndex bitIndex0 byte|
   524     |byteIndex bitIndex0 byte|
   525 
   525 
   526 %{  /* NOCONTEXT */
   526 %{  /* NOCONTEXT */
   527 
   527 
   530     int nIndex;
   530     int nIndex;
   531     REGISTER OBJ slf;
   531     REGISTER OBJ slf;
   532     REGISTER OBJ cls;
   532     REGISTER OBJ cls;
   533 
   533 
   534     if (0 /* __isSmallInteger(index) */) {
   534     if (0 /* __isSmallInteger(index) */) {
   535         indx = __intVal(index) - 1;
   535 	indx = __intVal(index) - 1;
   536         slf = self;
   536 	slf = self;
   537 
   537 
   538         byte = indx / 8;
   538 	byte = indx / 8;
   539         indx = indx % 8;
   539 	indx = indx % 8;
   540 
   540 
   541         if ((cls = __qClass(slf)) != @global(ByteArray)) {
   541 	if ((cls = __qClass(slf)) != @global(ByteArray)) {
   542             if (indx < 0) goto badIndex;
   542 	    if (indx < 0) goto badIndex;
   543             byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   543 	    byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   544         }
   544 	}
   545         nIndex = __byteArraySize(slf);
   545 	nIndex = __byteArraySize(slf);
   546         if ((unsigned)byte < (unsigned)nIndex) {
   546 	if ((unsigned)byte < (unsigned)nIndex) {
   547             __ByteArrayInstPtr(slf)->ba_element[byte] |= (1 << indx);
   547 	    __ByteArrayInstPtr(slf)->ba_element[byte] |= (1 << indx);
   548             RETURN (slf);
   548 	    RETURN (slf);
   549         }
   549 	}
   550     }
   550     }
   551 badIndex: ;
   551 badIndex: ;
   552 %}.
   552 %}.
   553     byteIndex := ((index-1) // 8) + 1.
   553     byteIndex := ((index-1) // 8) + 1.
   554     bitIndex0 := ((index-1) \\ 8).
   554     bitIndex0 := ((index-1) \\ 8).
   555     byte := self at:byteIndex.
   555     byte := self at:byteIndex.
   556     byte := byte bitOr:(1 bitShift:bitIndex0).
   556     byte := byte bitOr:(1 bitShift:bitIndex0).
   557     self at:byteIndex put:byte.
   557     self at:byteIndex put:byte.
   558 
   558 
   559     "
   559     "
   560      #[0 0 0 0] copy bitSetAt:1  
   560      #[0 0 0 0] copy bitSetAt:1
   561      #[0 0 0 0] copy bitSetAt:7  
   561      #[0 0 0 0] copy bitSetAt:7
   562      #[0 0 0 0] copy bitSetAt:8  
   562      #[0 0 0 0] copy bitSetAt:8
   563      #[0 0 0 0] copy bitSetAt:9  
   563      #[0 0 0 0] copy bitSetAt:9
   564     "
   564     "
   565    "
   565    "
   566      #[ 0 0 0 0 ] bitSetAt:1  
   566      #[ 0 0 0 0 ] bitSetAt:1
   567      #[ 0 0 0 0 ] bitSetAt:4  
   567      #[ 0 0 0 0 ] bitSetAt:4
   568      #[ 0 0 0 0 ] bitSetAt:8  
   568      #[ 0 0 0 0 ] bitSetAt:8
   569      #[ 0 0 0 0 ] bitSetAt:9  
   569      #[ 0 0 0 0 ] bitSetAt:9
   570      #[ 0 0 0 0 ] bitSetAt:10 
   570      #[ 0 0 0 0 ] bitSetAt:10
   571      #[ 0 0 0 0 ] bitSetAt:11 
   571      #[ 0 0 0 0 ] bitSetAt:11
   572    "
   572    "
   573 
   573 
   574 
   574 
   575 
   575 
   576 ! !
   576 ! !
   577 
   577 
   578 !ByteArray methodsFor:'accessing-bytes'!
   578 !ByteArray methodsFor:'accessing-bytes'!
   579 
   579 
   580 byteAt:index
   580 byteAt:index
   581     "return the byte at index. 
   581     "return the byte at index.
   582      For ByteArray, this is the same as basicAt:; 
   582      For ByteArray, this is the same as basicAt:;
   583      however, for strings or symbols, this returns a numeric byteValue
   583      however, for strings or symbols, this returns a numeric byteValue
   584      instead of a character."
   584      instead of a character."
   585 
   585 
   586 %{  /* NOCONTEXT */
   586 %{  /* NOCONTEXT */
   587 
   587 
   654 %{  /* NOCONTEXT */
   654 %{  /* NOCONTEXT */
   655 
   655 
   656     REGISTER int indx;
   656     REGISTER int indx;
   657     int nIndex;
   657     int nIndex;
   658     union {
   658     union {
   659         unsigned char u_char[4];
   659 	unsigned char u_char[4];
   660         unsigned int u_uint;
   660 	unsigned int u_uint;
   661     } val;
   661     } val;
   662     OBJ cls;
   662     OBJ cls;
   663     unsigned char *byteP;
   663     unsigned char *byteP;
   664 
   664 
   665     if (__isSmallInteger(index)) {
   665     if (__isSmallInteger(index)) {
   666         if (__isSmallInteger(value)) {
   666 	if (__isSmallInteger(value)) {
   667             val.u_uint = __intVal(value);
   667 	    val.u_uint = __intVal(value);
   668         } else {
   668 	} else {
   669             val.u_uint = __longIntVal(value);
   669 	    val.u_uint = __longIntVal(value);
   670             if (val.u_uint == 0) goto error;
   670 	    if (val.u_uint == 0) goto error;
   671         }
   671 	}
   672 
   672 
   673         indx = __intVal(index);
   673 	indx = __intVal(index);
   674         if (indx > 0) {
   674 	if (indx > 0) {
   675             if ((cls = __qClass(self)) != @global(ByteArray))
   675 	    if ((cls = __qClass(self)) != @global(ByteArray))
   676                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   676 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   677             nIndex = __qSize(self) - OHDR_SIZE;
   677 	    nIndex = __qSize(self) - OHDR_SIZE;
   678             if ((indx+3) <= nIndex) {
   678 	    if ((indx+3) <= nIndex) {
   679                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   679 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   680 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   680 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   681                 ((unsigned int *)byteP)[0] = val.u_uint; 
   681 		((unsigned int *)byteP)[0] = val.u_uint;
   682 #else
   682 #else
   683                 if (((unsigned INT)byteP & 3) == 0) {
   683 		if (((unsigned INT)byteP & 3) == 0) {
   684                     ((unsigned int *)byteP)[0] = val.u_uint; 
   684 		    ((unsigned int *)byteP)[0] = val.u_uint;
   685                 } else {
   685 		} else {
   686                     byteP[0] = val.u_char[0];
   686 		    byteP[0] = val.u_char[0];
   687                     byteP[1] = val.u_char[1];
   687 		    byteP[1] = val.u_char[1];
   688                     byteP[2] = val.u_char[2];
   688 		    byteP[2] = val.u_char[2];
   689                     byteP[3] = val.u_char[3];
   689 		    byteP[3] = val.u_char[3];
   690                 }
   690 		}
   691 #endif
   691 #endif
   692                 RETURN ( value );
   692 		RETURN ( value );
   693             }
   693 	    }
   694         }
   694 	}
   695     }
   695     }
   696   error: ;
   696   error: ;
   697 %}.
   697 %}.
   698     ^ super doubleWordAt:index put:value.
   698     ^ super doubleWordAt:index put:value.
   699 
   699 
   720     int val;
   720     int val;
   721     OBJ cls;
   721     OBJ cls;
   722     unsigned char *byteP;
   722     unsigned char *byteP;
   723 
   723 
   724     if (__isSmallInteger(index)) {
   724     if (__isSmallInteger(index)) {
   725         if (__isSmallInteger(value)) {
   725 	if (__isSmallInteger(value)) {
   726             val = __intVal(value);
   726 	    val = __intVal(value);
   727         } else {
   727 	} else {
   728             val = __longIntVal(value);
   728 	    val = __longIntVal(value);
   729             if (val == 0) goto error;
   729 	    if (val == 0) goto error;
   730         }
   730 	}
   731         indx = __intVal(index);
   731 	indx = __intVal(index);
   732         if (indx > 0) {
   732 	if (indx > 0) {
   733             if ((cls = __qClass(self)) != @global(ByteArray))
   733 	    if ((cls = __qClass(self)) != @global(ByteArray))
   734                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   734 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   735             nIndex = __qSize(self) - OHDR_SIZE;
   735 	    nIndex = __qSize(self) - OHDR_SIZE;
   736             if ((indx+3) <= nIndex) {
   736 	    if ((indx+3) <= nIndex) {
   737                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   737 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   738                 if (msb == true) {
   738 		if (msb == true) {
   739                     /*
   739 		    /*
   740                      * most significant byte first (i.e sparc order)
   740 		     * most significant byte first (i.e sparc order)
   741                      */
   741 		     */
   742 #if defined(__MSBFIRST__)
   742 #if defined(__MSBFIRST__)
   743                     if (((INT)byteP & 3) == 0) {
   743 		    if (((INT)byteP & 3) == 0) {
   744                         ((int *)byteP)[0] = val; 
   744 			((int *)byteP)[0] = val;
   745                     } else 
   745 		    } else
   746 #endif
   746 #endif
   747                     {
   747 		    {
   748                         byteP[3] = val & 0xFF;
   748 			byteP[3] = val & 0xFF;
   749                         val >>= 8;
   749 			val >>= 8;
   750                         byteP[2] = val & 0xFF;
   750 			byteP[2] = val & 0xFF;
   751                         val >>= 8;
   751 			val >>= 8;
   752                         byteP[1] = val & 0xFF;
   752 			byteP[1] = val & 0xFF;
   753                         val >>= 8;
   753 			val >>= 8;
   754                         byteP[0] = val & 0xFF;
   754 			byteP[0] = val & 0xFF;
   755                     }
   755 		    }
   756                 } else {
   756 		} else {
   757                     /*
   757 		    /*
   758                      * least significant byte first (i.e i386/alpha order)
   758 		     * least significant byte first (i.e i386/alpha order)
   759                      */
   759 		     */
   760 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   760 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   761                     ((int *)byteP)[0] = val;
   761 		    ((int *)byteP)[0] = val;
   762 #else
   762 #else
   763 # if defined(__LSBFIRST__)
   763 # if defined(__LSBFIRST__)
   764                     if (((unsigned INT)byteP & 3) == 0) {
   764 		    if (((unsigned INT)byteP & 3) == 0) {
   765                         ((int *)byteP)[0] = val; 
   765 			((int *)byteP)[0] = val;
   766                     } else 
   766 		    } else
   767 # endif
   767 # endif
   768                     {
   768 		    {
   769                         byteP[0] = val & 0xFF;
   769 			byteP[0] = val & 0xFF;
   770                         val >>= 8;
   770 			val >>= 8;
   771                         byteP[1] = val & 0xFF;
   771 			byteP[1] = val & 0xFF;
   772                         val >>= 8;
   772 			val >>= 8;
   773                         byteP[2] = val & 0xFF;
   773 			byteP[2] = val & 0xFF;
   774                         val >>= 8;
   774 			val >>= 8;
   775                         byteP[3] = val & 0xFF;
   775 			byteP[3] = val & 0xFF;
   776                     }
   776 		    }
   777 #endif
   777 #endif
   778                 }
   778 		}
   779                 RETURN ( value );
   779 		RETURN ( value );
   780             }
   780 	    }
   781         }
   781 	}
   782     }
   782     }
   783   error: ;
   783   error: ;
   784 %}.
   784 %}.
   785     ^ super doubleWordAt:index put:value MSB:msb
   785     ^ super doubleWordAt:index put:value MSB:msb
   786 
   786 
   803 %{  /* NOCONTEXT */
   803 %{  /* NOCONTEXT */
   804 
   804 
   805     REGISTER int indx;
   805     REGISTER int indx;
   806     int nIndex;
   806     int nIndex;
   807     union {
   807     union {
   808         unsigned char u_char[2];
   808 	unsigned char u_char[2];
   809         unsigned short u_ushort;
   809 	unsigned short u_ushort;
   810     } val;
   810     } val;
   811     OBJ cls;
   811     OBJ cls;
   812     unsigned char *byteP;
   812     unsigned char *byteP;
   813 
   813 
   814     if (__isSmallInteger(index)) {
   814     if (__isSmallInteger(index)) {
   815         indx = __intVal(index);
   815 	indx = __intVal(index);
   816         if (indx > 0) {
   816 	if (indx > 0) {
   817             if ((cls = __qClass(self)) != @global(ByteArray))
   817 	    if ((cls = __qClass(self)) != @global(ByteArray))
   818                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   818 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   819             nIndex = __byteArraySize(self);
   819 	    nIndex = __byteArraySize(self);
   820             if ((indx+1) <= nIndex) {
   820 	    if ((indx+1) <= nIndex) {
   821                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   821 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   822 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   822 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   823                 val.u_ushort = ((unsigned short *)byteP)[0]; 
   823 		val.u_ushort = ((unsigned short *)byteP)[0];
   824 #else
   824 #else
   825                 /*
   825 		/*
   826                  * mhmh to be measured:
   826 		 * mhmh to be measured:
   827                  *   the if may hurt more than the additional
   827 		 *   the if may hurt more than the additional
   828                  *   memory cycles on some machines ...
   828 		 *   memory cycles on some machines ...
   829                  */
   829 		 */
   830                 if (((INT)byteP & 1) == 0) {
   830 		if (((INT)byteP & 1) == 0) {
   831                     /* aligned */
   831 		    /* aligned */
   832                     val.u_ushort = ((unsigned short *)byteP)[0]; 
   832 		    val.u_ushort = ((unsigned short *)byteP)[0];
   833                 } else {
   833 		} else {
   834                     val.u_char[0] = byteP[0];
   834 		    val.u_char[0] = byteP[0];
   835                     val.u_char[1] = byteP[1];
   835 		    val.u_char[1] = byteP[1];
   836                 }
   836 		}
   837 #endif
   837 #endif
   838                 RETURN ( __MKSMALLINT(val.u_ushort) );
   838 		RETURN ( __MKSMALLINT(val.u_ushort) );
   839             }
   839 	    }
   840         }
   840 	}
   841     }
   841     }
   842 %}.
   842 %}.
   843     ^ super wordAt:index
   843     ^ super wordAt:index
   844 !
   844 !
   845 
   845 
   856     int val;
   856     int val;
   857     OBJ cls;
   857     OBJ cls;
   858     unsigned char *byteP;
   858     unsigned char *byteP;
   859 
   859 
   860     if (__isSmallInteger(index)) {
   860     if (__isSmallInteger(index)) {
   861         indx = __intVal(index);
   861 	indx = __intVal(index);
   862         if (indx > 0) {
   862 	if (indx > 0) {
   863             if ((cls = __qClass(self)) != @global(ByteArray))
   863 	    if ((cls = __qClass(self)) != @global(ByteArray))
   864                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   864 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   865             nIndex = __byteArraySize(self);
   865 	    nIndex = __byteArraySize(self);
   866             if ((indx+1) <= nIndex) {
   866 	    if ((indx+1) <= nIndex) {
   867                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   867 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   868                 if (msb == true) {
   868 		if (msb == true) {
   869                     /*
   869 		    /*
   870                      * most significant byte first (i.e sparc order)
   870 		     * most significant byte first (i.e sparc order)
   871                      */
   871 		     */
   872 #if defined(__MSBFIRST__)
   872 #if defined(__MSBFIRST__)
   873                     /*
   873 		    /*
   874                      * mhmh to be measured:
   874 		     * mhmh to be measured:
   875                      *   the if may hurt more than the additional
   875 		     *   the if may hurt more than the additional
   876                      *   memory cycles on some machines ...
   876 		     *   memory cycles on some machines ...
   877                      */
   877 		     */
   878                     if (((INT)byteP & 1) == 0) {
   878 		    if (((INT)byteP & 1) == 0) {
   879                         /* aligned */
   879 			/* aligned */
   880                         val = ((unsigned short *)byteP)[0]; 
   880 			val = ((unsigned short *)byteP)[0];
   881                     } else
   881 		    } else
   882 #endif
   882 #endif
   883                     {
   883 		    {
   884                         val = byteP[0];
   884 			val = byteP[0];
   885                         val = (val << 8) + byteP[1];
   885 			val = (val << 8) + byteP[1];
   886                     }
   886 		    }
   887                 } else {
   887 		} else {
   888                     /*
   888 		    /*
   889                      * least significant byte first (i.e i386/alpha order)
   889 		     * least significant byte first (i.e i386/alpha order)
   890                      */
   890 		     */
   891 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   891 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   892                     val = ((unsigned short *)byteP)[0];
   892 		    val = ((unsigned short *)byteP)[0];
   893 #else
   893 #else
   894 # if defined(__LSBFIRST__)
   894 # if defined(__LSBFIRST__)
   895                     /*
   895 		    /*
   896                      * mhmh to be measured:
   896 		     * mhmh to be measured:
   897                      *   the if may hurt more than the additional
   897 		     *   the if may hurt more than the additional
   898                      *   memory cycles on some machines ...
   898 		     *   memory cycles on some machines ...
   899                      */
   899 		     */
   900                     if (((INT)byteP & 1) == 0) {
   900 		    if (((INT)byteP & 1) == 0) {
   901                         /* aligned */
   901 			/* aligned */
   902                         val = ((unsigned short *)byteP)[0];
   902 			val = ((unsigned short *)byteP)[0];
   903                     } else
   903 		    } else
   904 # endif
   904 # endif
   905                     {
   905 		    {
   906                         val = byteP[1];
   906 			val = byteP[1];
   907                         val = (val << 8) + byteP[0];
   907 			val = (val << 8) + byteP[0];
   908                     }
   908 		    }
   909 #endif
   909 #endif
   910                 }
   910 		}
   911                 RETURN ( __MKSMALLINT(val) );
   911 		RETURN ( __MKSMALLINT(val) );
   912             }
   912 	    }
   913         }
   913 	}
   914     }
   914     }
   915 %}.
   915 %}.
   916     ^ super wordAt:index MSB:msb
   916     ^ super wordAt:index MSB:msb
   917 
   917 
   918 !
   918 !
   919 
   919 
   920 wordAt:index put:value
   920 wordAt:index put:value
   921     "set the 2-bytes starting at index from the (unsigned) Integer value.
   921     "set the 2-bytes starting at index from the (unsigned) Integer value.
   922      The stored value must be in the range 0 .. 16rFFFF. 
   922      The stored value must be in the range 0 .. 16rFFFF.
   923      The value is stored in the machines natural byteorder,
   923      The value is stored in the machines natural byteorder,
   924      i.e. this method should only be used to fill byteArrays which are
   924      i.e. this method should only be used to fill byteArrays which are
   925      used internally (not passed to other machines).
   925      used internally (not passed to other machines).
   926      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   926      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   927 
   927 
   929 
   929 
   930     REGISTER int indx;
   930     REGISTER int indx;
   931     int nIndex;
   931     int nIndex;
   932     int v;
   932     int v;
   933     union {
   933     union {
   934         unsigned char u_char[2];
   934 	unsigned char u_char[2];
   935         unsigned short u_ushort;
   935 	unsigned short u_ushort;
   936     } val;
   936     } val;
   937     OBJ cls;
   937     OBJ cls;
   938     unsigned char *byteP;
   938     unsigned char *byteP;
   939 
   939 
   940     if (__bothSmallInteger(index, value)) {
   940     if (__bothSmallInteger(index, value)) {
   941         indx = __intVal(index);
   941 	indx = __intVal(index);
   942         if (indx > 0) {
   942 	if (indx > 0) {
   943             if ((cls = __qClass(self)) != @global(ByteArray))
   943 	    if ((cls = __qClass(self)) != @global(ByteArray))
   944                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   944 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   945             nIndex = __byteArraySize(self);
   945 	    nIndex = __byteArraySize(self);
   946             if ((indx+1) <= nIndex) {
   946 	    if ((indx+1) <= nIndex) {
   947                 val.u_ushort = v = __intVal(value);
   947 		val.u_ushort = v = __intVal(value);
   948                 if ((v & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   948 		if ((v & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   949                     byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   949 		    byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   950 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   950 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   951                     ((unsigned short *)byteP)[0] = val.u_ushort;
   951 		    ((unsigned short *)byteP)[0] = val.u_ushort;
   952 #else
   952 #else
   953                     /*
   953 		    /*
   954                      * mhmh to be measured:
   954 		     * mhmh to be measured:
   955                      *   the if may hurt more than the additional
   955 		     *   the if may hurt more than the additional
   956                      *   memory cycles on some machines ...
   956 		     *   memory cycles on some machines ...
   957                      */
   957 		     */
   958                     if (((INT)byteP & 1) == 0) {
   958 		    if (((INT)byteP & 1) == 0) {
   959                         /* aligned */
   959 			/* aligned */
   960                         ((unsigned short *)byteP)[0] = val.u_ushort;
   960 			((unsigned short *)byteP)[0] = val.u_ushort;
   961                     } else {
   961 		    } else {
   962                         byteP[0] = val.u_char[0];
   962 			byteP[0] = val.u_char[0];
   963                         byteP[1] = val.u_char[1];
   963 			byteP[1] = val.u_char[1];
   964                     }
   964 		    }
   965 #endif
   965 #endif
   966                     RETURN ( value );
   966 		    RETURN ( value );
   967                 }
   967 		}
   968             }
   968 	    }
   969         }
   969 	}
   970     }
   970     }
   971 %}.
   971 %}.
   972     ^ super wordAt:index put:value
   972     ^ super wordAt:index put:value
   973 
   973 
   974     "
   974     "
   975      |b|
   975      |b|
   976      b := ByteArray new:4.
   976      b := ByteArray new:4.
   977      b wordAt:1 put:16r0102.
   977      b wordAt:1 put:16r0102.
   978      b wordAt:3 put:16r0304.
   978      b wordAt:3 put:16r0304.
   979      b inspect  
   979      b inspect
   980     "
   980     "
   981 !
   981 !
   982 
   982 
   983 wordAt:index put:value MSB:msb
   983 wordAt:index put:value MSB:msb
   984     "set the 2-bytes starting at index from the (unsigned) Integer value.
   984     "set the 2-bytes starting at index from the (unsigned) Integer value.
   985      The stored value must be in the range 0 .. 16rFFFF. 
   985      The stored value must be in the range 0 .. 16rFFFF.
   986      The value is stored LSB-first (i.e. the low 8bits are stored at the
   986      The value is stored LSB-first (i.e. the low 8bits are stored at the
   987      lower index) if msb is false, MSB-first otherwise.
   987      lower index) if msb is false, MSB-first otherwise.
   988      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   988      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   989 
   989 
   990 %{  /* NOCONTEXT */
   990 %{  /* NOCONTEXT */
   994     int val;
   994     int val;
   995     OBJ cls;
   995     OBJ cls;
   996     unsigned char *byteP;
   996     unsigned char *byteP;
   997 
   997 
   998     if (__bothSmallInteger(index, value)) {
   998     if (__bothSmallInteger(index, value)) {
   999         indx = __intVal(index);
   999 	indx = __intVal(index);
  1000         if (indx > 0) {
  1000 	if (indx > 0) {
  1001             if ((cls = __qClass(self)) != @global(ByteArray))
  1001 	    if ((cls = __qClass(self)) != @global(ByteArray))
  1002                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1002 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1003             nIndex = __byteArraySize(self);
  1003 	    nIndex = __byteArraySize(self);
  1004             if ((indx+1) <= nIndex) {
  1004 	    if ((indx+1) <= nIndex) {
  1005                 val = __intVal(value);
  1005 		val = __intVal(value);
  1006                 if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
  1006 		if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
  1007                     byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
  1007 		    byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
  1008                     if (msb == true) {
  1008 		    if (msb == true) {
  1009                         /*
  1009 			/*
  1010                          * most significant byte first (i.e sparc order)
  1010 			 * most significant byte first (i.e sparc order)
  1011                          */
  1011 			 */
  1012 #if defined(__MSBFIRST__)
  1012 #if defined(__MSBFIRST__)
  1013                         /*
  1013 			/*
  1014                          * mhmh to be measured:
  1014 			 * mhmh to be measured:
  1015                          *   the if may hurt more than the additional
  1015 			 *   the if may hurt more than the additional
  1016                          *   memory cycles on some machines ...
  1016 			 *   memory cycles on some machines ...
  1017                          */
  1017 			 */
  1018                         if (((INT)byteP & 1) == 0) {
  1018 			if (((INT)byteP & 1) == 0) {
  1019                             /* aligned */
  1019 			    /* aligned */
  1020                             ((unsigned short *)byteP)[0] = val;
  1020 			    ((unsigned short *)byteP)[0] = val;
  1021                         } else 
  1021 			} else
  1022 #endif
  1022 #endif
  1023                         {
  1023 			{
  1024                             byteP[1] = val & 0xFF;
  1024 			    byteP[1] = val & 0xFF;
  1025                             byteP[0] = (val>>8) & 0xFF;
  1025 			    byteP[0] = (val>>8) & 0xFF;
  1026                         }
  1026 			}
  1027                     } else {
  1027 		    } else {
  1028                         /*
  1028 			/*
  1029                          * least significant byte first (i.e i386/alpha order)
  1029 			 * least significant byte first (i.e i386/alpha order)
  1030                          */
  1030 			 */
  1031 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
  1031 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
  1032                         ((unsigned short *)byteP)[0] = val;
  1032 			((unsigned short *)byteP)[0] = val;
  1033 #else
  1033 #else
  1034 # if defined(__LSBFIRST__)
  1034 # if defined(__LSBFIRST__)
  1035                         /*
  1035 			/*
  1036                          * mhmh to be measured:
  1036 			 * mhmh to be measured:
  1037                          *   the if may hurt more than the additional
  1037 			 *   the if may hurt more than the additional
  1038                          *   memory cycles on some machines ...
  1038 			 *   memory cycles on some machines ...
  1039                          */
  1039 			 */
  1040                         if (((INT)byteP & 1) == 0) {
  1040 			if (((INT)byteP & 1) == 0) {
  1041                             /* aligned */
  1041 			    /* aligned */
  1042                             ((unsigned short *)byteP)[0] = val;
  1042 			    ((unsigned short *)byteP)[0] = val;
  1043                         } else 
  1043 			} else
  1044 # endif
  1044 # endif
  1045                         {
  1045 			{
  1046                             byteP[0] = val & 0xFF;
  1046 			    byteP[0] = val & 0xFF;
  1047                             byteP[1] = (val>>8) & 0xFF;
  1047 			    byteP[1] = (val>>8) & 0xFF;
  1048                         }
  1048 			}
  1049 #endif
  1049 #endif
  1050                     }
  1050 		    }
  1051                     RETURN ( value );
  1051 		    RETURN ( value );
  1052                 }
  1052 		}
  1053             }
  1053 	    }
  1054         }
  1054 	}
  1055     }
  1055     }
  1056 %}.
  1056 %}.
  1057     ^ super wordAt:index put:value MSB:msb
  1057     ^ super wordAt:index put:value MSB:msb
  1058 
  1058 
  1059     "
  1059     "
  1061      b := ByteArray new:8.
  1061      b := ByteArray new:8.
  1062      b wordAt:1 put:16r0102 MSB:false.
  1062      b wordAt:1 put:16r0102 MSB:false.
  1063      b wordAt:3 put:16r0304 MSB:false.
  1063      b wordAt:3 put:16r0304 MSB:false.
  1064      b wordAt:5 put:16r0102 MSB:true.
  1064      b wordAt:5 put:16r0102 MSB:true.
  1065      b wordAt:7 put:16r0304 MSB:true.
  1065      b wordAt:7 put:16r0304 MSB:true.
  1066      b inspect  
  1066      b inspect
  1067     "
  1067     "
  1068 ! !
  1068 ! !
  1069 
  1069 
  1070 !ByteArray methodsFor:'binary storage'!
  1070 !ByteArray methodsFor:'binary storage'!
  1071 
  1071 
  1077 
  1077 
  1078     |myClass myBasicSize|
  1078     |myClass myBasicSize|
  1079 
  1079 
  1080     "not, if I have named instance variables"
  1080     "not, if I have named instance variables"
  1081     (myClass := self class) instSize ~~ 0 ifTrue:[
  1081     (myClass := self class) instSize ~~ 0 ifTrue:[
  1082         ^ super storeBinaryDefinitionOn:stream manager:manager
  1082 	^ super storeBinaryDefinitionOn:stream manager:manager
  1083     ].
  1083     ].
  1084 
  1084 
  1085     myBasicSize := self basicSize.
  1085     myBasicSize := self basicSize.
  1086 
  1086 
  1087     "/ can use a more compact representation;
  1087     "/ can use a more compact representation;
  1088     "/ but not for subclasses ...
  1088     "/ but not for subclasses ...
  1089 
  1089 
  1090     ((myClass == ByteArray) 
  1090     ((myClass == ByteArray)
  1091     and:[myBasicSize <= 255]) ifTrue:[
  1091     and:[myBasicSize <= 255]) ifTrue:[
  1092         "/ special encoding: <codeForByteArray> <len> <bytes> ...
  1092 	"/ special encoding: <codeForByteArray> <len> <bytes> ...
  1093         stream nextPut:(manager codeForByteArray); nextPut:myBasicSize.
  1093 	stream nextPut:(manager codeForByteArray); nextPut:myBasicSize.
  1094     ] ifFalse:[
  1094     ] ifFalse:[
  1095         manager putIdOfClass:myClass on:stream.
  1095 	manager putIdOfClass:myClass on:stream.
  1096         stream nextNumber:4 put:myBasicSize.
  1096 	stream nextNumber:4 put:myBasicSize.
  1097     ].
  1097     ].
  1098     self storeBinaryElementsOn:stream.
  1098     self storeBinaryElementsOn:stream.
  1099 
  1099 
  1100     "Modified: / 2.11.1997 / 15:28:45 / cg"
  1100     "Modified: / 2.11.1997 / 15:28:45 / cg"
  1101 !
  1101 !
  1191 	^ self
  1191 	^ self
  1192     ].
  1192     ].
  1193     ^ super asByteArray
  1193     ^ super asByteArray
  1194 
  1194 
  1195     "
  1195     "
  1196      'hello world' asByteArray 
  1196      'hello world' asByteArray
  1197      #(1 2 3 4 5 6 7) asByteArray 
  1197      #(1 2 3 4 5 6 7) asByteArray
  1198      #(1 2 256 4 5 6 7) asByteArray 
  1198      #(1 2 256 4 5 6 7) asByteArray
  1199     "
  1199     "
  1200 !
  1200 !
  1201 
  1201 
  1202 asPackedString
  1202 asPackedString
  1203     "ST-80 compatibility: encode the receiver into an ascii String
  1203     "ST-80 compatibility: encode the receiver into an ascii String
  1208      encoded in the last character.
  1208      encoded in the last character.
  1209      ST-80 uses this encoding for Images ...
  1209      ST-80 uses this encoding for Images ...
  1210      This is very similar (but not equal) to the algorithm used in RFC1421.
  1210      This is very similar (but not equal) to the algorithm used in RFC1421.
  1211      PS: I dont like it ;-)"
  1211      PS: I dont like it ;-)"
  1212 
  1212 
  1213     |outStream 
  1213     |outStream
  1214      index     "{ Class:SmallInteger}"
  1214      index     "{ Class:SmallInteger}"
  1215      nextIndex "{ Class:SmallInteger}"
  1215      nextIndex "{ Class:SmallInteger}"
  1216      stop      "{ Class:SmallInteger}"
  1216      stop      "{ Class:SmallInteger}"
  1217      n         "{ Class:SmallInteger}"
  1217      n         "{ Class:SmallInteger}"
  1218      mod       "{ Class:SmallInteger}"
  1218      mod       "{ Class:SmallInteger}"
  1219      cpl|
  1219      cpl|
  1220 
  1220 
  1221     outStream := WriteStream on:String new.
  1221     outStream := WriteStream on:String new.
  1222     index := 1. 
  1222     index := 1.
  1223     stop := self size.
  1223     stop := self size.
  1224 
  1224 
  1225     stop > 100 ifTrue:[
  1225     stop > 100 ifTrue:[
  1226         "/ cg:
  1226 	"/ cg:
  1227         "/ initial lineBreak 
  1227 	"/ initial lineBreak
  1228         outStream cr.
  1228 	outStream cr.
  1229     ].
  1229     ].
  1230     cpl := 0.
  1230     cpl := 0.
  1231 
  1231 
  1232     [index <= stop] whileTrue:[
  1232     [index <= stop] whileTrue:[
  1233         "take 3 source bytes"
  1233 	"take 3 source bytes"
  1234         n := (self at:index) bitShift:16.
  1234 	n := (self at:index) bitShift:16.
  1235         (index < stop) ifTrue:[
  1235 	(index < stop) ifTrue:[
  1236             nextIndex := index + 1.
  1236 	    nextIndex := index + 1.
  1237             n := n bitOr:((self at:nextIndex) bitShift:8).
  1237 	    n := n bitOr:((self at:nextIndex) bitShift:8).
  1238             (nextIndex < stop) ifTrue:[
  1238 	    (nextIndex < stop) ifTrue:[
  1239                 n := n bitOr:(self at:(index + 2)).
  1239 		n := n bitOr:(self at:(index + 2)).
  1240             ].
  1240 	    ].
  1241         ].
  1241 	].
  1242 
  1242 
  1243         "took me a while to find that one out ..."
  1243 	"took me a while to find that one out ..."
  1244         n := n bitXor:16r820820.
  1244 	n := n bitXor:16r820820.
  1245 
  1245 
  1246         outStream nextPut:(Character value:(n bitShift:-18) + 32).
  1246 	outStream nextPut:(Character value:(n bitShift:-18) + 32).
  1247         outStream nextPut:(Character value:((n bitShift:-12) bitAnd:16r3F) + 32).
  1247 	outStream nextPut:(Character value:((n bitShift:-12) bitAnd:16r3F) + 32).
  1248         outStream nextPut:(Character value:((n bitShift:-6) bitAnd:16r3F) + 32).
  1248 	outStream nextPut:(Character value:((n bitShift:-6) bitAnd:16r3F) + 32).
  1249         outStream nextPut:(Character value:(n bitAnd:16r3F) + 32).
  1249 	outStream nextPut:(Character value:(n bitAnd:16r3F) + 32).
  1250         index := index + 3.
  1250 	index := index + 3.
  1251 
  1251 
  1252         "/ cg:
  1252 	"/ cg:
  1253         "/ lineBreak after every 120 characters
  1253 	"/ lineBreak after every 120 characters
  1254         "/ fromPackedString will ignore those
  1254 	"/ fromPackedString will ignore those
  1255         cpl := cpl + 4.
  1255 	cpl := cpl + 4.
  1256         cpl >= 120 ifTrue:[
  1256 	cpl >= 120 ifTrue:[
  1257             outStream cr.
  1257 	    outStream cr.
  1258             cpl := 0.
  1258 	    cpl := 0.
  1259         ].
  1259 	].
  1260     ].
  1260     ].
  1261     (mod := stop \\ 3) ~~ 0 ifTrue:[
  1261     (mod := stop \\ 3) ~~ 0 ifTrue:[
  1262         outStream backStep.
  1262 	outStream backStep.
  1263         outStream nextPut:(Character value:(mod + 96)).
  1263 	outStream nextPut:(Character value:(mod + 96)).
  1264     ].
  1264     ].
  1265     ^ outStream contents
  1265     ^ outStream contents
  1266 
  1266 
  1267     "Modified: 12.11.1996 / 15:45:02 / cg"
  1267     "Modified: 12.11.1996 / 15:45:02 / cg"
  1268 !
  1268 !
  1271     "speed up string conversions"
  1271     "speed up string conversions"
  1272 
  1272 
  1273     |size|
  1273     |size|
  1274 
  1274 
  1275     self class == ByteArray ifTrue:[
  1275     self class == ByteArray ifTrue:[
  1276         size := self size.
  1276 	size := self size.
  1277         ^ (String uninitializedNew:size) replaceBytesFrom:1 to:size with:self startingAt:1.
  1277 	^ (String uninitializedNew:size) replaceBytesFrom:1 to:size with:self startingAt:1.
  1278     ].
  1278     ].
  1279     ^ super asString
  1279     ^ super asString
  1280 
  1280 
  1281     "
  1281     "
  1282       #[60 61 62 63] asString
  1282       #[60 61 62 63] asString
  1297      can be reconstructed with #decodeAsLiteralArray."
  1297      can be reconstructed with #decodeAsLiteralArray."
  1298 
  1298 
  1299     ^ self
  1299     ^ self
  1300 
  1300 
  1301     "
  1301     "
  1302      #[1 2 3] literalArrayEncoding   
  1302      #[1 2 3] literalArrayEncoding
  1303     "
  1303     "
  1304 
  1304 
  1305 
  1305 
  1306 ! !
  1306 ! !
  1307 
  1307 
  1309 
  1309 
  1310 copy
  1310 copy
  1311     "redefined for a bit more speed"
  1311     "redefined for a bit more speed"
  1312 
  1312 
  1313     self class == ByteArray ifTrue:[
  1313     self class == ByteArray ifTrue:[
  1314         ^ self copyFrom:1 to:(self size)
  1314 	^ self copyFrom:1 to:(self size)
  1315     ].
  1315     ].
  1316     ^ super copy
  1316     ^ super copy
  1317 !
  1317 !
  1318 
  1318 
  1319 copyFrom:start to:stop
  1319 copyFrom:start to:stop
  1329     int len, index1, index2, sz;
  1329     int len, index1, index2, sz;
  1330     OBJ newByteArray;
  1330     OBJ newByteArray;
  1331 
  1331 
  1332     if (__isByteArray(self)
  1332     if (__isByteArray(self)
  1333      && __bothSmallInteger(start, stop)) {
  1333      && __bothSmallInteger(start, stop)) {
  1334         len = __byteArraySize(self);
  1334 	len = __byteArraySize(self);
  1335         index1 = __intVal(start);
  1335 	index1 = __intVal(start);
  1336         index2 = __intVal(stop);
  1336 	index2 = __intVal(stop);
  1337 
  1337 
  1338         if ((index1 <= index2) && (index1 > 0)) {
  1338 	if ((index1 <= index2) && (index1 > 0)) {
  1339             if (index2 <= len) {
  1339 	    if (index2 <= len) {
  1340                 count = index2 - index1 + 1;
  1340 		count = index2 - index1 + 1;
  1341                 __PROTECT_CONTEXT__
  1341 		__PROTECT_CONTEXT__
  1342                 sz = OHDR_SIZE + count;
  1342 		sz = OHDR_SIZE + count;
  1343                 __qNew(newByteArray, sz);       /* OBJECT ALLOCATION */
  1343 		__qNew(newByteArray, sz);       /* OBJECT ALLOCATION */
  1344                 __UNPROTECT_CONTEXT__
  1344 		__UNPROTECT_CONTEXT__
  1345                 if (newByteArray != nil) {
  1345 		if (newByteArray != nil) {
  1346                     __InstPtr(newByteArray)->o_class = ByteArray;
  1346 		    __InstPtr(newByteArray)->o_class = ByteArray;
  1347                     __qSTORE(newByteArray, ByteArray);
  1347 		    __qSTORE(newByteArray, ByteArray);
  1348                     dstp = __ByteArrayInstPtr(newByteArray)->ba_element;
  1348 		    dstp = __ByteArrayInstPtr(newByteArray)->ba_element;
  1349                     srcp = __ByteArrayInstPtr(self)->ba_element + index1 - 1;
  1349 		    srcp = __ByteArrayInstPtr(self)->ba_element + index1 - 1;
  1350 
  1350 
  1351 #ifdef bcopy4
  1351 #ifdef bcopy4
  1352                     if (((unsigned INT)srcp & 3) == ((unsigned INT)dstp & 3)) {
  1352 		    if (((unsigned INT)srcp & 3) == ((unsigned INT)dstp & 3)) {
  1353                         int nW;
  1353 			int nW;
  1354 
  1354 
  1355                         /* copy unaligned part */
  1355 			/* copy unaligned part */
  1356                         while (count && (((unsigned INT)srcp & 3) != 0)) {
  1356 			while (count && (((unsigned INT)srcp & 3) != 0)) {
  1357                             *dstp++ = *srcp++;
  1357 			    *dstp++ = *srcp++;
  1358                             count--;
  1358 			    count--;
  1359                         }
  1359 			}
  1360                         if (count) {
  1360 			if (count) {
  1361                             /* copy aligned part */
  1361 			    /* copy aligned part */
  1362                             nW = count >> 2;
  1362 			    nW = count >> 2;
  1363                             if (count & 3) {
  1363 			    if (count & 3) {
  1364                                 nW++;
  1364 				nW++;
  1365                             }
  1365 			    }
  1366                             bcopy4(srcp, dstp, nW);
  1366 			    bcopy4(srcp, dstp, nW);
  1367                         }
  1367 			}
  1368                         RETURN ( newByteArray );
  1368 			RETURN ( newByteArray );
  1369                     }
  1369 		    }
  1370 #endif /* bcopy4 */
  1370 #endif /* bcopy4 */
  1371 #if __POINTER_SIZE__ == 8
  1371 #if __POINTER_SIZE__ == 8
  1372                     if (((unsigned INT)srcp & 7) == ((unsigned INT)dstp & 7)) {
  1372 		    if (((unsigned INT)srcp & 7) == ((unsigned INT)dstp & 7)) {
  1373                         int nW;
  1373 			int nW;
  1374 
  1374 
  1375                         /* copy unaligned part */
  1375 			/* copy unaligned part */
  1376                         while (count && (((unsigned INT)srcp & 7) != 0)) {
  1376 			while (count && (((unsigned INT)srcp & 7) != 0)) {
  1377                             *dstp++ = *srcp++;
  1377 			    *dstp++ = *srcp++;
  1378                             count--;
  1378 			    count--;
  1379                         }
  1379 			}
  1380                         /* copy aligned part */
  1380 			/* copy aligned part */
  1381                         while (count >= 8) {
  1381 			while (count >= 8) {
  1382                             ((unsigned INT *)dstp)[0] = ((unsigned INT *)srcp)[0];
  1382 			    ((unsigned INT *)dstp)[0] = ((unsigned INT *)srcp)[0];
  1383                             dstp += 8;
  1383 			    dstp += 8;
  1384                             srcp += 8;
  1384 			    srcp += 8;
  1385                             count -= 8;
  1385 			    count -= 8;
  1386                         }
  1386 			}
  1387                         /* copy remaining part */
  1387 			/* copy remaining part */
  1388                         while (count) {
  1388 			while (count) {
  1389                             *dstp++ = *srcp++;
  1389 			    *dstp++ = *srcp++;
  1390                             count--;
  1390 			    count--;
  1391                         }
  1391 			}
  1392                         RETURN ( newByteArray );
  1392 			RETURN ( newByteArray );
  1393                     }
  1393 		    }
  1394 #endif /* bcopy4 */
  1394 #endif /* bcopy4 */
  1395 
  1395 
  1396 #ifdef FAST_MEMCPY
  1396 #ifdef FAST_MEMCPY
  1397                     bcopy(srcp, dstp, count);
  1397 		    bcopy(srcp, dstp, count);
  1398 #else
  1398 #else
  1399                     while (count--) {
  1399 		    while (count--) {
  1400                         *dstp++ = *srcp++;
  1400 			*dstp++ = *srcp++;
  1401                     }
  1401 		    }
  1402 #endif
  1402 #endif
  1403                     RETURN ( newByteArray );
  1403 		    RETURN ( newByteArray );
  1404                 }
  1404 		}
  1405             }
  1405 	    }
  1406         }
  1406 	}
  1407     }
  1407     }
  1408 %}.
  1408 %}.
  1409     "
  1409     "
  1410      fall back in case of non-integer index or out-of-bound index;
  1410      fall back in case of non-integer index or out-of-bound index;
  1411      will eventually lead to an out-of-bound signal raise
  1411      will eventually lead to an out-of-bound signal raise
  1412     "
  1412     "
  1413     ^ super copyFrom:start to:stop
  1413     ^ super copyFrom:start to:stop
  1414 
  1414 
  1415     "
  1415     "
  1416      #[1 2 3 4 5 6 7 8 9 10] copyFrom:1 to:10    
  1416      #[1 2 3 4 5 6 7 8 9 10] copyFrom:1 to:10
  1417      #[1 2 3 4 5 6 7 8 9 10] copyFrom:5 to:7  
  1417      #[1 2 3 4 5 6 7 8 9 10] copyFrom:5 to:7
  1418 
  1418 
  1419      #[1 2 3 4 5 6 7 8 9 10] copyFrom:5 to:11    
  1419      #[1 2 3 4 5 6 7 8 9 10] copyFrom:5 to:11
  1420      #[1 2 3 4 5 6 7 8 9 10] copyFrom:0 to:10    
  1420      #[1 2 3 4 5 6 7 8 9 10] copyFrom:0 to:10
  1421      #[1 2 3 4 5 6 7 8 9 10] copyFrom:0 to:9    
  1421      #[1 2 3 4 5 6 7 8 9 10] copyFrom:0 to:9
  1422     "
  1422     "
  1423 !
  1423 !
  1424 
  1424 
  1425 shallowCopy
  1425 shallowCopy
  1426     "redefined for a bit more speed"
  1426     "redefined for a bit more speed"
  1427 
  1427 
  1428     self class == ByteArray ifTrue:[
  1428     self class == ByteArray ifTrue:[
  1429         ^ self copyFrom:1 to:(self size)
  1429 	^ self copyFrom:1 to:(self size)
  1430     ].
  1430     ].
  1431     ^ super shallowCopy
  1431     ^ super shallowCopy
  1432 !
  1432 !
  1433 
  1433 
  1434 symbolFrom:start to:stop
  1434 symbolFrom:start to:stop
  1435     "make a symbol from the characters of the subcollection starting 
  1435     "make a symbol from the characters of the subcollection starting
  1436      at index start, anInteger and ending at stop, anInteger.
  1436      at index start, anInteger and ending at stop, anInteger.
  1437      This saves us garbage and character copying."
  1437      This saves us garbage and character copying."
  1438 
  1438 
  1439     |sym|
  1439     |sym|
  1440 
  1440 
  1520 	    len -= nInst;
  1520 	    len -= nInst;
  1521 	}
  1521 	}
  1522 
  1522 
  1523 	value = __intVal(aNumber);
  1523 	value = __intVal(aNumber);
  1524 	if (((unsigned)value <= 0xFF) /* i.e. (value >= 0) && (value <= 255) */
  1524 	if (((unsigned)value <= 0xFF) /* i.e. (value >= 0) && (value <= 255) */
  1525 	 && (index1 <= index2) 
  1525 	 && (index1 <= index2)
  1526 	 && (index1 > 0)) {
  1526 	 && (index1 > 0)) {
  1527 	    if (index2 <= len) {
  1527 	    if (index2 <= len) {
  1528 		count = index2 - index1 + 1;
  1528 		count = index2 - index1 + 1;
  1529 
  1529 
  1530 #ifdef memset4
  1530 #ifdef memset4
  1551 		    }
  1551 		    }
  1552 		    RETURN (self);
  1552 		    RETURN (self);
  1553 		}
  1553 		}
  1554 #endif /* memset4 */
  1554 #endif /* memset4 */
  1555 
  1555 
  1556 #if __POINTER_SIZE__ == 8
  1556 #if (__POINTER_SIZE__ == 8)
  1557 		{
  1557 		{
  1558 		    INT v8;
  1558 		    INT v8;
  1559 
  1559 
  1560 		    v8 = (value << 8) | value;
  1560 		    v8 = (value << 8) | value;
  1561 		    v8 = (v8 << 16) | v8;
  1561 		    v8 = (v8 << 16) | v8;
  1594 		    if (count) {
  1594 		    if (count) {
  1595 			*dstp = value;
  1595 			*dstp = value;
  1596 		    }
  1596 		    }
  1597 		    RETURN (self);
  1597 		    RETURN (self);
  1598 		}
  1598 		}
  1599 #endif /* alpha64 */
  1599 #endif /* 64bit */
  1600 
  1600 
  1601 #ifdef FAST_MEMSET
  1601 #ifdef FAST_MEMSET
  1602 		memset(dstp, value, count);
  1602 		memset(dstp, value, count);
  1603 #else
  1603 #else
  1604 # ifdef UNROLL_LOOPS
  1604 # ifdef UNROLL_LOOPS
  1623      will eventually lead to an out-of-bound signal raise
  1623      will eventually lead to an out-of-bound signal raise
  1624     "
  1624     "
  1625     ^ super from:start to:stop put:aNumber
  1625     ^ super from:start to:stop put:aNumber
  1626 
  1626 
  1627     "
  1627     "
  1628      (ByteArray new:10) from:1 to:10 put:1 
  1628      (ByteArray new:10) from:1 to:10 put:1
  1629      (ByteArray new:20) from:10 to:20 put:1 
  1629      (ByteArray new:20) from:10 to:20 put:1
  1630      (ByteArray new:20) from:1 to:10 put:1 
  1630      (ByteArray new:20) from:1 to:10 put:1
  1631     "
  1631     "
  1632 !
  1632 !
  1633 
  1633 
  1634 replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1634 replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1635     "replace elements from another collection, which must be a ByteArray-
  1635     "replace elements from another collection, which must be a ByteArray-
  1651 #ifndef NO_PRIM_BYTEARR
  1651 #ifndef NO_PRIM_BYTEARR
  1652     if ((__isBytes(aCollection) || __isExternalBytesLike(aCollection))
  1652     if ((__isBytes(aCollection) || __isExternalBytesLike(aCollection))
  1653      && __isBytes(self)
  1653      && __isBytes(self)
  1654      && __bothSmallInteger(start, stop)
  1654      && __bothSmallInteger(start, stop)
  1655      && __isSmallInteger(repStart)) {
  1655      && __isSmallInteger(repStart)) {
  1656         startIndex = __intVal(start) - 1;
  1656 	startIndex = __intVal(start) - 1;
  1657         if (startIndex >= 0) {
  1657 	if (startIndex >= 0) {
  1658             dst = (__ByteArrayInstPtr(self)->ba_element) + startIndex;
  1658 	    dst = (__ByteArrayInstPtr(self)->ba_element) + startIndex;
  1659             nIndex = __byteArraySize(self);
  1659 	    nIndex = __byteArraySize(self);
  1660 
  1660 
  1661             if ((cls = __qClass(self)) != @global(ByteArray)) {
  1661 	    if ((cls = __qClass(self)) != @global(ByteArray)) {
  1662                 int nInst;
  1662 		int nInst;
  1663 
  1663 
  1664                 nInst = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1664 		nInst = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1665                 dst += nInst;
  1665 		dst += nInst;
  1666                 nIndex -= nInst;
  1666 		nIndex -= nInst;
  1667             }
  1667 	    }
  1668 
  1668 
  1669             stopIndex = __intVal(stop) - 1;
  1669 	    stopIndex = __intVal(stop) - 1;
  1670             count = stopIndex - startIndex + 1;
  1670 	    count = stopIndex - startIndex + 1;
  1671             if (count == 0) {
  1671 	    if (count == 0) {
  1672                 RETURN ( self );
  1672 		RETURN ( self );
  1673             }
  1673 	    }
  1674 
  1674 
  1675             if ((count > 0) && (stopIndex < nIndex)) {
  1675 	    if ((count > 0) && (stopIndex < nIndex)) {
  1676                 repStartIndex = __intVal(repStart) - 1;
  1676 		repStartIndex = __intVal(repStart) - 1;
  1677                 if (repStartIndex >= 0) {
  1677 		if (repStartIndex >= 0) {
  1678                     if (__isExternalBytesLike(aCollection)) {
  1678 		    if (__isExternalBytesLike(aCollection)) {
  1679                         OBJ sz;
  1679 			OBJ sz;
  1680 
  1680 
  1681                         src = __externalAddressVal(aCollection);
  1681 			src = __externalAddressVal(aCollection);
  1682                         if (src == 0) goto fallBack;
  1682 			if (src == 0) goto fallBack;
  1683 
  1683 
  1684                         sz = __externalBytesSize(aCollection);
  1684 			sz = __externalBytesSize(aCollection);
  1685                         if (__isSmallInteger(sz)) {
  1685 			if (__isSmallInteger(sz)) {
  1686                             repNIndex = __smallIntegerVal(sz);
  1686 			    repNIndex = __smallIntegerVal(sz);
  1687                         } else {
  1687 			} else {
  1688                             repNIndex = repStopIndex+1; /* always enough */
  1688 			    repNIndex = repStopIndex+1; /* always enough */
  1689                         }
  1689 			}
  1690                         src = src + repStartIndex;
  1690 			src = src + repStartIndex;
  1691                     } else {
  1691 		    } else {
  1692                         repNIndex = __qSize(aCollection) - OHDR_SIZE;
  1692 			repNIndex = __qSize(aCollection) - OHDR_SIZE;
  1693                         src = (__ByteArrayInstPtr(aCollection)->ba_element) + repStartIndex;
  1693 			src = (__ByteArrayInstPtr(aCollection)->ba_element) + repStartIndex;
  1694                         if ((cls = __qClass(aCollection)) != @global(ByteArray)) {
  1694 			if ((cls = __qClass(aCollection)) != @global(ByteArray)) {
  1695                             int nInst;
  1695 			    int nInst;
  1696 
  1696 
  1697                             nInst = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1697 			    nInst = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1698                             src += nInst;
  1698 			    src += nInst;
  1699                             repNIndex -= nInst;
  1699 			    repNIndex -= nInst;
  1700                         }
  1700 			}
  1701                     }
  1701 		    }
  1702                     repStopIndex = repStartIndex + (stopIndex - startIndex);
  1702 		    repStopIndex = repStartIndex + (stopIndex - startIndex);
  1703                     if (repStopIndex < repNIndex) {
  1703 		    if (repStopIndex < repNIndex) {
  1704                         if (aCollection == self) {
  1704 			if (aCollection == self) {
  1705                             /* take care of overlapping copy */
  1705 			    /* take care of overlapping copy */
  1706                             if (src < dst) {
  1706 			    if (src < dst) {
  1707                                 /* must do a reverse copy */
  1707 				/* must do a reverse copy */
  1708                                 src += count;
  1708 				src += count;
  1709                                 dst += count;
  1709 				dst += count;
  1710                                 while (count-- > 0) {
  1710 				while (count-- > 0) {
  1711                                     *--dst = *--src;
  1711 				    *--dst = *--src;
  1712                                 }
  1712 				}
  1713                                 RETURN ( self );
  1713 				RETURN ( self );
  1714                             }
  1714 			    }
  1715                         }
  1715 			}
  1716 
  1716 
  1717 # ifdef bcopy4
  1717 # ifdef bcopy4
  1718                         if (((unsigned INT)src & 3) == ((unsigned INT)dst & 3)) {
  1718 			if (((unsigned INT)src & 3) == ((unsigned INT)dst & 3)) {
  1719                             int nW;
  1719 			    int nW;
  1720 
  1720 
  1721                             /* copy unaligned part */
  1721 			    /* copy unaligned part */
  1722                             while (count && ((unsigned INT)src & 3)) {
  1722 			    while (count && ((unsigned INT)src & 3)) {
  1723                                 *dst++ = *src++;
  1723 				*dst++ = *src++;
  1724                                 count--;
  1724 				count--;
  1725                             }
  1725 			    }
  1726 
  1726 
  1727                             if (count > 0) {
  1727 			    if (count > 0) {
  1728                                 /* copy aligned part */
  1728 				/* copy aligned part */
  1729                                 nW = count >> 2;
  1729 				nW = count >> 2;
  1730                                 bcopy4(src, dst, nW);
  1730 				bcopy4(src, dst, nW);
  1731                                 if ((count = count & 3) != 0) {
  1731 				if ((count = count & 3) != 0) {
  1732                                     /* copy any remaining part */
  1732 				    /* copy any remaining part */
  1733                                     src += (nW<<2);
  1733 				    src += (nW<<2);
  1734                                     dst += (nW<<2);
  1734 				    dst += (nW<<2);
  1735                                     while (count--) {
  1735 				    while (count--) {
  1736                                         *dst++ = *src++;
  1736 					*dst++ = *src++;
  1737                                     }
  1737 				    }
  1738                                 }
  1738 				}
  1739                             }
  1739 			    }
  1740                             RETURN ( self );
  1740 			    RETURN ( self );
  1741                         }
  1741 			}
  1742 # else
  1742 # else
  1743 #  if __POINTER_SIZE__ == 8
  1743 #  if __POINTER_SIZE__ == 8
  1744                         if (((unsigned INT)src & 7) == ((unsigned INT)dst & 7)) {
  1744 			if (((unsigned INT)src & 7) == ((unsigned INT)dst & 7)) {
  1745                             /* copy unaligned part */
  1745 			    /* copy unaligned part */
  1746                             while (count && ((unsigned INT)src & 7)) {
  1746 			    while (count && ((unsigned INT)src & 7)) {
  1747                                 *dst++ = *src++;
  1747 				*dst++ = *src++;
  1748                                 count--;
  1748 				count--;
  1749                             }
  1749 			    }
  1750 
  1750 
  1751                             /* copy aligned part */
  1751 			    /* copy aligned part */
  1752                             while (count >= 8) {
  1752 			    while (count >= 8) {
  1753                                 ((unsigned INT *)dst)[0] = ((unsigned INT *)src)[0];
  1753 				((unsigned INT *)dst)[0] = ((unsigned INT *)src)[0];
  1754                                 dst += 8;
  1754 				dst += 8;
  1755                                 src += 8;
  1755 				src += 8;
  1756                                 count -= 8;
  1756 				count -= 8;
  1757                             }
  1757 			    }
  1758                             while (count--) {
  1758 			    while (count--) {
  1759                                 *dst++ = *src++;
  1759 				*dst++ = *src++;
  1760                             }
  1760 			    }
  1761                             RETURN ( self );
  1761 			    RETURN ( self );
  1762                         }
  1762 			}
  1763 #  endif /* alpha64 */
  1763 #  endif /* 64bit */
  1764 # endif /* bcopy4 */
  1764 # endif /* bcopy4 */
  1765 
  1765 
  1766 # ifdef FAST_MEMCPY
  1766 # ifdef FAST_MEMCPY
  1767                         bcopy(src, dst, count);
  1767 			bcopy(src, dst, count);
  1768 # else
  1768 # else
  1769 #  ifdef UNROLL_LOOPS
  1769 #  ifdef UNROLL_LOOPS
  1770                         while (count >= 8) {
  1770 			while (count >= 8) {
  1771                             dst[0] = src[0]; dst[1] = src[1];
  1771 			    dst[0] = src[0]; dst[1] = src[1];
  1772                             dst[2] = src[2]; dst[3] = src[3];
  1772 			    dst[2] = src[2]; dst[3] = src[3];
  1773                             dst[4] = src[4]; dst[5] = src[5];
  1773 			    dst[4] = src[4]; dst[5] = src[5];
  1774                             dst[6] = src[6]; dst[7] = src[7];
  1774 			    dst[6] = src[6]; dst[7] = src[7];
  1775                             dst += 8; src += 8;
  1775 			    dst += 8; src += 8;
  1776                             count -= 8;
  1776 			    count -= 8;
  1777                         }
  1777 			}
  1778 #  endif /* UNROLL_LOOPS */
  1778 #  endif /* UNROLL_LOOPS */
  1779                         while (count-- > 0) {
  1779 			while (count-- > 0) {
  1780                             *dst++ = *src++;
  1780 			    *dst++ = *src++;
  1781                         }
  1781 			}
  1782 # endif
  1782 # endif
  1783                         RETURN ( self );
  1783 			RETURN ( self );
  1784                     }
  1784 		    }
  1785                 }
  1785 		}
  1786             }
  1786 	    }
  1787         }
  1787 	}
  1788     }
  1788     }
  1789 fallBack: ;
  1789 fallBack: ;
  1790 #endif
  1790 #endif
  1791 %}.
  1791 %}.
  1792     "
  1792     "
  1795     "
  1795     "
  1796     ^ super replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1796     ^ super replaceBytesFrom:start to:stop with:aCollection startingAt:repStart
  1797 
  1797 
  1798     "
  1798     "
  1799      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1799      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1800         copy 
  1800 	copy
  1801             replaceFrom:1 to:8 
  1801 	    replaceFrom:1 to:8
  1802             with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1802 	    with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1803             startingAt:1
  1803 	    startingAt:1
  1804 
  1804 
  1805      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1805      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1806         copy 
  1806 	copy
  1807             replaceFrom:3 to:10 
  1807 	    replaceFrom:3 to:10
  1808             with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1808 	    with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1809             startingAt:1
  1809 	    startingAt:1
  1810 
  1810 
  1811      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1811      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1812         copy 
  1812 	copy
  1813             replaceFrom:3 to:4 
  1813 	    replaceFrom:3 to:4
  1814             with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1814 	    with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1815             startingAt:1
  1815 	    startingAt:1
  1816 
  1816 
  1817      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1817      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1818         copy 
  1818 	copy
  1819             replaceFrom:0 to:9 
  1819 	    replaceFrom:0 to:9
  1820             with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1820 	    with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1821             startingAt:1
  1821 	    startingAt:1
  1822 
  1822 
  1823      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1823      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16]
  1824         copy 
  1824 	copy
  1825             replaceFrom:1 to:10 
  1825 	    replaceFrom:1 to:10
  1826             with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1826 	    with:#[10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160]
  1827             startingAt:0
  1827 	    startingAt:0
  1828     "
  1828     "
  1829 !
  1829 !
  1830 
  1830 
  1831 replaceBytesFrom:startIndex with:replacementCollection startingAt:repStartIndex
  1831 replaceBytesFrom:startIndex with:replacementCollection startingAt:repStartIndex
  1832     "replace elements from another collection, which must be
  1832     "replace elements from another collection, which must be
  1833      byte-array-like.
  1833      byte-array-like.
  1834 
  1834 
  1835      Notice: This operation modifies the receiver, NOT a copy;
  1835      Notice: This operation modifies the receiver, NOT a copy;
  1836      therefore the change may affect all others referencing the receiver."
  1836      therefore the change may affect all others referencing the receiver."
  1837 
  1837 
  1838     ^ self 
  1838     ^ self
  1839 	replaceBytesFrom:startIndex 
  1839 	replaceBytesFrom:startIndex
  1840 	to:(startIndex + replacementCollection size - repStartIndex)
  1840 	to:(startIndex + replacementCollection size - repStartIndex)
  1841 	with:replacementCollection
  1841 	with:replacementCollection
  1842 	startingAt:repStartIndex
  1842 	startingAt:repStartIndex
  1843 
  1843 
  1844     "
  1844     "
  1859      Return the receiver.
  1859      Return the receiver.
  1860 
  1860 
  1861      Notice: This operation modifies the receiver, NOT a copy;
  1861      Notice: This operation modifies the receiver, NOT a copy;
  1862      therefore the change may affect all others referencing the receiver."
  1862      therefore the change may affect all others referencing the receiver."
  1863 
  1863 
  1864     ((aCollection class == self class) 
  1864     ((aCollection class == self class)
  1865     or:[aCollection class isBytes]) ifTrue:[
  1865     or:[aCollection class isBytes]) ifTrue:[
  1866 	^ self replaceBytesFrom:startIndex to:stopIndex with:aCollection startingAt:repStartIndex
  1866 	^ self replaceBytesFrom:startIndex to:stopIndex with:aCollection startingAt:repStartIndex
  1867     ].
  1867     ].
  1868     ^ super replaceFrom:startIndex to:stopIndex with:aCollection startingAt:repStartIndex
  1868     ^ super replaceFrom:startIndex to:stopIndex with:aCollection startingAt:repStartIndex
  1869 
  1869 
  1879     "Modified: / 27.7.1998 / 16:58:33 / cg"
  1879     "Modified: / 27.7.1998 / 16:58:33 / cg"
  1880 ! !
  1880 ! !
  1881 
  1881 
  1882 !ByteArray methodsFor:'image manipulation support'!
  1882 !ByteArray methodsFor:'image manipulation support'!
  1883 
  1883 
  1884 bitAndBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart 
  1884 bitAndBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart
  1885     "replace bytes in the receiver with the result of a bitAnd operation.
  1885     "replace bytes in the receiver with the result of a bitAnd operation.
  1886      Warning: this is a destructive operation - elements in the receiver are overwritten."
  1886      Warning: this is a destructive operation - elements in the receiver are overwritten."
  1887 
  1887 
  1888     ^ self bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:#bitAnd:
  1888     ^ self bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:#bitAnd:
  1889 
  1889 
  1890     "
  1890     "
  1891      #[1 2 3 4 5 6 7 8]
  1891      #[1 2 3 4 5 6 7 8]
  1892 	bitAndBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 
  1892 	bitAndBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1
  1893      #[1 2 3 4 5 6 7 8]
  1893      #[1 2 3 4 5 6 7 8]
  1894 	bitAndBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1
  1894 	bitAndBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1
  1895     "
  1895     "
  1896 
  1896 
  1897 !
  1897 !
  1898 
  1898 
  1899 bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:ruleSymbol
  1899 bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:ruleSymbol
  1900     "perform a special case of an aligned bitBlit operation.
  1900     "perform a special case of an aligned bitBlit operation.
  1901      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result 
  1901      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result
  1902      of some logical operation, as specified by the ruleSymbol.
  1902      of some logical operation, as specified by the ruleSymbol.
  1903      SourceBytes are fetched starting at sourceOffset.
  1903      SourceBytes are fetched starting at sourceOffset.
  1904      Valid rule symbols are:
  1904      Valid rule symbols are:
  1905         #copy    - trivial;  same as replaceBytesFrom:to:with:startingAt:
  1905 	#copy    - trivial;  same as replaceBytesFrom:to:with:startingAt:
  1906         #bitXor: - xoring;   byte[dI] = byte[dI] bitXor:(srcByte[sI])
  1906 	#bitXor: - xoring;   byte[dI] = byte[dI] bitXor:(srcByte[sI])
  1907         #bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:(srcByte[sI])
  1907 	#bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:(srcByte[sI])
  1908         #bitOr:  - oring;    byte[dI] = byte[dI] bitOr:(srcByte[sI])
  1908 	#bitOr:  - oring;    byte[dI] = byte[dI] bitOr:(srcByte[sI])
  1909         #+       - adding;   byte[dI] = (byte[dI] + (srcByte[sI])) mod: 256
  1909 	#+       - adding;   byte[dI] = (byte[dI] + (srcByte[sI])) mod: 256
  1910         #-       - subtract; byte[dI] = (byte[dI] - (srcByte[sI])) mod: 256
  1910 	#-       - subtract; byte[dI] = (byte[dI] - (srcByte[sI])) mod: 256
  1911      Warning: this is a destructive operation - elements in the receiver are overwritten.
  1911      Warning: this is a destructive operation - elements in the receiver are overwritten.
  1912     "
  1912     "
  1913 
  1913 
  1914     |srcIdx|
  1914     |srcIdx|
  1915 
  1915 
  1916 %{
  1916 %{
  1917     if ((__isByteArray(sourceBytes)) 
  1917     if ((__isByteArray(sourceBytes))
  1918      && (__qClass(self) == ByteArray)
  1918      && (__qClass(self) == ByteArray)
  1919      && __isSmallInteger(dstStart)
  1919      && __isSmallInteger(dstStart)
  1920      && __isSmallInteger(dstEnd)
  1920      && __isSmallInteger(dstEnd)
  1921      && __isSmallInteger(sourceStart)) {
  1921      && __isSmallInteger(sourceStart)) {
  1922         unsigned char *srcP = __ByteArrayInstPtr(sourceBytes)->ba_element;
  1922 	unsigned char *srcP = __ByteArrayInstPtr(sourceBytes)->ba_element;
  1923         unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
  1923 	unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
  1924         int srcLen = __byteArraySize(sourceBytes);
  1924 	int srcLen = __byteArraySize(sourceBytes);
  1925         int dstLen = __byteArraySize(self);
  1925 	int dstLen = __byteArraySize(self);
  1926         int __srcStart = __intVal(sourceStart);
  1926 	int __srcStart = __intVal(sourceStart);
  1927         int __dstStart = __intVal(dstStart);
  1927 	int __dstStart = __intVal(dstStart);
  1928         int count = __intVal(dstEnd) - __dstStart + 1;
  1928 	int count = __intVal(dstEnd) - __dstStart + 1;
  1929 
  1929 
  1930         if ((__dstStart >= 1)
  1930 	if ((__dstStart >= 1)
  1931          && (__srcStart >= 1)
  1931 	 && (__srcStart >= 1)
  1932          && ((__dstStart + count - 1) <= dstLen)
  1932 	 && ((__dstStart + count - 1) <= dstLen)
  1933          && ((__srcStart + count - 1) <= srcLen)) {
  1933 	 && ((__srcStart + count - 1) <= srcLen)) {
  1934             srcP += __srcStart - 1;
  1934 	    srcP += __srcStart - 1;
  1935             dstP += __dstStart - 1;
  1935 	    dstP += __dstStart - 1;
  1936 
  1936 
  1937 #define OP_LOOP_BYTES(OP) \
  1937 #define OP_LOOP_BYTES(OP) \
  1938     while (count > 0) {                                              \
  1938     while (count > 0) {                                              \
  1939         *dstP OP (*srcP);                                            \
  1939 	*dstP OP (*srcP);                                            \
  1940         srcP++;                                                      \
  1940 	srcP++;                                                      \
  1941         dstP++;                                                      \
  1941 	dstP++;                                                      \
  1942         count--;                                                     \
  1942 	count--;                                                     \
  1943     }                                                                
  1943     }
  1944 
  1944 
  1945 #define OP_LOOP(OP) \
  1945 #define OP_LOOP(OP) \
  1946     while (count >= 16) {                                            \
  1946     while (count >= 16) {                                            \
  1947         ((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1947 	((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1948         ((unsigned int *)dstP)[1] OP (((unsigned int *)srcP)[1]);    \
  1948 	((unsigned int *)dstP)[1] OP (((unsigned int *)srcP)[1]);    \
  1949         ((unsigned int *)dstP)[2] OP (((unsigned int *)srcP)[2]);    \
  1949 	((unsigned int *)dstP)[2] OP (((unsigned int *)srcP)[2]);    \
  1950         ((unsigned int *)dstP)[3] OP (((unsigned int *)srcP)[3]);    \
  1950 	((unsigned int *)dstP)[3] OP (((unsigned int *)srcP)[3]);    \
  1951         srcP += 16;                                                  \
  1951 	srcP += 16;                                                  \
  1952         dstP += 16;                                                  \
  1952 	dstP += 16;                                                  \
  1953         count -= 16;                                                 \
  1953 	count -= 16;                                                 \
  1954     }                                                                \
  1954     }                                                                \
  1955     while (count >= 4) {                                             \
  1955     while (count >= 4) {                                             \
  1956         ((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1956 	((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1957         srcP += 4;                                                   \
  1957 	srcP += 4;                                                   \
  1958         dstP += 4;                                                   \
  1958 	dstP += 4;                                                   \
  1959         count -= 4;                                                  \
  1959 	count -= 4;                                                  \
  1960     }                                                                \
  1960     }                                                                \
  1961     while (count > 0) {                                              \
  1961     while (count > 0) {                                              \
  1962         *dstP OP (*srcP);                                            \
  1962 	*dstP OP (*srcP);                                            \
  1963         srcP++;                                                      \
  1963 	srcP++;                                                      \
  1964         dstP++;                                                      \
  1964 	dstP++;                                                      \
  1965         count--;                                                     \
  1965 	count--;                                                     \
  1966     }                                                                
  1966     }
  1967 
  1967 
  1968 
  1968 
  1969             if (ruleSymbol == @symbol(bitXor:)) {
  1969 	    if (ruleSymbol == @symbol(bitXor:)) {
  1970                 OP_LOOP( ^= )
  1970 		OP_LOOP( ^= )
  1971                 RETURN (self);
  1971 		RETURN (self);
  1972             }
  1972 	    }
  1973             if (ruleSymbol == @symbol(bitXorNot:)) {
  1973 	    if (ruleSymbol == @symbol(bitXorNot:)) {
  1974                 OP_LOOP( ^=~ )
  1974 		OP_LOOP( ^=~ )
  1975                 RETURN (self);
  1975 		RETURN (self);
  1976             }
  1976 	    }
  1977             if (ruleSymbol == @symbol(bitAnd:)) {
  1977 	    if (ruleSymbol == @symbol(bitAnd:)) {
  1978                 OP_LOOP( &= )
  1978 		OP_LOOP( &= )
  1979                 RETURN (self);
  1979 		RETURN (self);
  1980             }
  1980 	    }
  1981             if (ruleSymbol == @symbol(bitAndNot:)) {
  1981 	    if (ruleSymbol == @symbol(bitAndNot:)) {
  1982                 OP_LOOP( &=~ )
  1982 		OP_LOOP( &=~ )
  1983                 RETURN (self);
  1983 		RETURN (self);
  1984             }
  1984 	    }
  1985             if (ruleSymbol == @symbol(bitOr:)) {
  1985 	    if (ruleSymbol == @symbol(bitOr:)) {
  1986                 OP_LOOP( |= )
  1986 		OP_LOOP( |= )
  1987                 RETURN (self);
  1987 		RETURN (self);
  1988             }
  1988 	    }
  1989             if (ruleSymbol == @symbol(bitOrNot:)) {
  1989 	    if (ruleSymbol == @symbol(bitOrNot:)) {
  1990                 OP_LOOP( |=~ )
  1990 		OP_LOOP( |=~ )
  1991                 RETURN (self);
  1991 		RETURN (self);
  1992             }
  1992 	    }
  1993             if (ruleSymbol == @symbol(copy)) {
  1993 	    if (ruleSymbol == @symbol(copy)) {
  1994                 OP_LOOP( = )
  1994 		OP_LOOP( = )
  1995                 RETURN (self);
  1995 		RETURN (self);
  1996             }
  1996 	    }
  1997             if (ruleSymbol == @symbol(copyNot)) {
  1997 	    if (ruleSymbol == @symbol(copyNot)) {
  1998                 OP_LOOP( =~ )
  1998 		OP_LOOP( =~ )
  1999                 RETURN (self);
  1999 		RETURN (self);
  2000             }
  2000 	    }
  2001             if (ruleSymbol == @symbol(+)) {
  2001 	    if (ruleSymbol == @symbol(+)) {
  2002                 OP_LOOP_BYTES( += )
  2002 		OP_LOOP_BYTES( += )
  2003                 RETURN (self);
  2003 		RETURN (self);
  2004             }
  2004 	    }
  2005             if (ruleSymbol == @symbol(-)) {
  2005 	    if (ruleSymbol == @symbol(-)) {
  2006                 OP_LOOP_BYTES( -= )
  2006 		OP_LOOP_BYTES( -= )
  2007                 RETURN (self);
  2007 		RETURN (self);
  2008             }
  2008 	    }
  2009         }
  2009 	}
  2010     }
  2010     }
  2011 #undef OP_LOOP_BYTES
  2011 #undef OP_LOOP_BYTES
  2012 #undef OP_LOOP
  2012 #undef OP_LOOP
  2013 
  2013 
  2014 %}.
  2014 %}.
  2015     ruleSymbol == #copy ifTrue:[
  2015     ruleSymbol == #copy ifTrue:[
  2016         self replaceFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart.
  2016 	self replaceFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart.
  2017         ^ self
  2017 	^ self
  2018     ].
  2018     ].
  2019 
  2019 
  2020     srcIdx := sourceStart.
  2020     srcIdx := sourceStart.
  2021     dstStart to:dstEnd do:[:dstIdx |
  2021     dstStart to:dstEnd do:[:dstIdx |
  2022         self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:(sourceBytes at:srcIdx)).
  2022 	self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:(sourceBytes at:srcIdx)).
  2023         srcIdx := srcIdx + 1.
  2023 	srcIdx := srcIdx + 1.
  2024     ].
  2024     ].
  2025 
  2025 
  2026     "
  2026     "
  2027      #[1 2 3 4 5 6 7 8]
  2027      #[1 2 3 4 5 6 7 8]
  2028         bitBlitBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  2028 	bitBlitBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  2029      #[1 2 3 4 5 6 7 8]
  2029      #[1 2 3 4 5 6 7 8]
  2030         bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  2030 	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  2031      #[1 2 3 4 5 6 7 8]
  2031      #[1 2 3 4 5 6 7 8]
  2032         bitBlitBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#bitAnd:
  2032 	bitBlitBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#bitAnd:
  2033      #[1 2 3 4 5 6 7 8]
  2033      #[1 2 3 4 5 6 7 8]
  2034         bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+  
  2034 	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+
  2035      #[255 0 0 0 0 0 0 0]
  2035      #[255 0 0 0 0 0 0 0]
  2036         bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+   
  2036 	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+
  2037      #[1 2 3 4 5 6 7 8]
  2037      #[1 2 3 4 5 6 7 8]
  2038         bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#+
  2038 	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#+
  2039      #[1 2 3 4 5 6 7 8]
  2039      #[1 2 3 4 5 6 7 8]
  2040         bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#+
  2040 	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#+
  2041      #[1 2 3 4 5 6 7 8]
  2041      #[1 2 3 4 5 6 7 8]
  2042         bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#copyNot
  2042 	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#copyNot
  2043 
  2043 
  2044      #[1 2 3 4 5 6 7 8]
  2044      #[1 2 3 4 5 6 7 8]
  2045         bitBlitBytesFrom:1 to:8 with:(1 to:8) startingAt:1 rule:#+
  2045 	bitBlitBytesFrom:1 to:8 with:(1 to:8) startingAt:1 rule:#+
  2046     "
  2046     "
  2047 !
  2047 !
  2048 
  2048 
  2049 bitBlitBytesFrom:dstStart to:dstEnd withConstant:sourceByte rule:ruleSymbol
  2049 bitBlitBytesFrom:dstStart to:dstEnd withConstant:sourceByte rule:ruleSymbol
  2050     "perform a special case of an aligned bitBlit operation.
  2050     "perform a special case of an aligned bitBlit operation.
  2051      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result 
  2051      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result
  2052      of some logical operation, as specified by the ruleSymbol.
  2052      of some logical operation, as specified by the ruleSymbol.
  2053      Valid rule symbols are:
  2053      Valid rule symbols are:
  2054         #copy    - trivial;  same as from:to:put:
  2054 	#copy    - trivial;  same as from:to:put:
  2055         #bitXor: - xoring;   byte[dI] = byte[dI] bitXor:sourceConst
  2055 	#bitXor: - xoring;   byte[dI] = byte[dI] bitXor:sourceConst
  2056         #bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:sourceConst
  2056 	#bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:sourceConst
  2057         #bitOr:  - oring;    byte[dI] = byte[dI] bitOr:sourceConst
  2057 	#bitOr:  - oring;    byte[dI] = byte[dI] bitOr:sourceConst
  2058         #+       - adding;   byte[dI] = (byte[dI] + sourceConst) mod: 256
  2058 	#+       - adding;   byte[dI] = (byte[dI] + sourceConst) mod: 256
  2059         #-       - subtract; byte[dI] = (byte[dI] - sourceConst) mod: 256
  2059 	#-       - subtract; byte[dI] = (byte[dI] - sourceConst) mod: 256
  2060      Warning: this is a destructive operation - elements in the receiver are overwritten.
  2060      Warning: this is a destructive operation - elements in the receiver are overwritten.
  2061     "
  2061     "
  2062 
  2062 
  2063     |srcIdx|
  2063     |srcIdx|
  2064 
  2064 
  2065 %{
  2065 %{
  2066     if ((__qClass(self) == ByteArray)
  2066     if ((__qClass(self) == ByteArray)
  2067      && __isSmallInteger(dstStart)
  2067      && __isSmallInteger(dstStart)
  2068      && __isSmallInteger(dstEnd)
  2068      && __isSmallInteger(dstEnd)
  2069      && __isSmallInteger(sourceByte)) {
  2069      && __isSmallInteger(sourceByte)) {
  2070         unsigned char srcByte = __intVal(sourceByte);
  2070 	unsigned char srcByte = __intVal(sourceByte);
  2071         unsigned srcWord;
  2071 	unsigned srcWord;
  2072         unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
  2072 	unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
  2073         int dstLen = __byteArraySize(self);
  2073 	int dstLen = __byteArraySize(self);
  2074         int __dstStart = __intVal(dstStart);
  2074 	int __dstStart = __intVal(dstStart);
  2075         int count = __intVal(dstEnd) - __dstStart + 1;
  2075 	int count = __intVal(dstEnd) - __dstStart + 1;
  2076 
  2076 
  2077         srcWord = (srcByte << 8) | srcByte;
  2077 	srcWord = (srcByte << 8) | srcByte;
  2078         srcWord = (srcWord << 16) | srcWord;
  2078 	srcWord = (srcWord << 16) | srcWord;
  2079 
  2079 
  2080         if ((__dstStart >= 1)
  2080 	if ((__dstStart >= 1)
  2081          && ((__dstStart + count - 1) <= dstLen)) {
  2081 	 && ((__dstStart + count - 1) <= dstLen)) {
  2082             dstP += __dstStart - 1;
  2082 	    dstP += __dstStart - 1;
  2083 
  2083 
  2084 #define OP_LOOP_BYTES(OP) \
  2084 #define OP_LOOP_BYTES(OP) \
  2085     while (count > 0) {                          \
  2085     while (count > 0) {                          \
  2086         *dstP OP srcByte;                        \
  2086 	*dstP OP srcByte;                        \
  2087         dstP++;                                  \
  2087 	dstP++;                                  \
  2088         count--;                                 \
  2088 	count--;                                 \
  2089     }                                                                
  2089     }
  2090 
  2090 
  2091 #define OP_LOOP(OP) \
  2091 #define OP_LOOP(OP) \
  2092     while (count >= 16) {                        \
  2092     while (count >= 16) {                        \
  2093         ((unsigned int *)dstP)[0] OP srcWord;    \
  2093 	((unsigned int *)dstP)[0] OP srcWord;    \
  2094         ((unsigned int *)dstP)[1] OP srcWord;    \
  2094 	((unsigned int *)dstP)[1] OP srcWord;    \
  2095         ((unsigned int *)dstP)[2] OP srcWord;    \
  2095 	((unsigned int *)dstP)[2] OP srcWord;    \
  2096         ((unsigned int *)dstP)[3] OP srcWord;    \
  2096 	((unsigned int *)dstP)[3] OP srcWord;    \
  2097         dstP += 16;                              \
  2097 	dstP += 16;                              \
  2098         count -= 16;                             \
  2098 	count -= 16;                             \
  2099     }                                            \
  2099     }                                            \
  2100     while (count >= 4) {                         \
  2100     while (count >= 4) {                         \
  2101         ((unsigned int *)dstP)[0] OP srcWord;    \
  2101 	((unsigned int *)dstP)[0] OP srcWord;    \
  2102         dstP += 4;                               \
  2102 	dstP += 4;                               \
  2103         count -= 4;                              \
  2103 	count -= 4;                              \
  2104     }                                            \
  2104     }                                            \
  2105     while (count > 0) {                          \
  2105     while (count > 0) {                          \
  2106         *dstP OP srcByte;                        \
  2106 	*dstP OP srcByte;                        \
  2107         dstP++;                                  \
  2107 	dstP++;                                  \
  2108         count--;                                 \
  2108 	count--;                                 \
  2109     }                                                                
  2109     }
  2110 
  2110 
  2111 
  2111 
  2112             if (ruleSymbol == @symbol(bitXor:)) {
  2112 	    if (ruleSymbol == @symbol(bitXor:)) {
  2113                 OP_LOOP( ^= )
  2113 		OP_LOOP( ^= )
  2114                 RETURN (self);
  2114 		RETURN (self);
  2115             }
  2115 	    }
  2116             if (ruleSymbol == @symbol(bitXorNot:)) {
  2116 	    if (ruleSymbol == @symbol(bitXorNot:)) {
  2117                 OP_LOOP( ^=~ )
  2117 		OP_LOOP( ^=~ )
  2118                 RETURN (self);
  2118 		RETURN (self);
  2119             }
  2119 	    }
  2120             if (ruleSymbol == @symbol(bitAnd:)) {
  2120 	    if (ruleSymbol == @symbol(bitAnd:)) {
  2121                 OP_LOOP( &= )
  2121 		OP_LOOP( &= )
  2122                 RETURN (self);
  2122 		RETURN (self);
  2123             }
  2123 	    }
  2124             if (ruleSymbol == @symbol(bitAndNot:)) {
  2124 	    if (ruleSymbol == @symbol(bitAndNot:)) {
  2125                 OP_LOOP( &=~ )
  2125 		OP_LOOP( &=~ )
  2126                 RETURN (self);
  2126 		RETURN (self);
  2127             }
  2127 	    }
  2128             if (ruleSymbol == @symbol(bitOr:)) {
  2128 	    if (ruleSymbol == @symbol(bitOr:)) {
  2129                 OP_LOOP( |= )
  2129 		OP_LOOP( |= )
  2130                 RETURN (self);
  2130 		RETURN (self);
  2131             }
  2131 	    }
  2132             if (ruleSymbol == @symbol(bitOrNot:)) {
  2132 	    if (ruleSymbol == @symbol(bitOrNot:)) {
  2133                 OP_LOOP( |=~ )
  2133 		OP_LOOP( |=~ )
  2134                 RETURN (self);
  2134 		RETURN (self);
  2135             }
  2135 	    }
  2136             if (ruleSymbol == @symbol(copy)) {
  2136 	    if (ruleSymbol == @symbol(copy)) {
  2137                 OP_LOOP( = )
  2137 		OP_LOOP( = )
  2138                 RETURN (self);
  2138 		RETURN (self);
  2139             }
  2139 	    }
  2140             if (ruleSymbol == @symbol(copyNot)) {
  2140 	    if (ruleSymbol == @symbol(copyNot)) {
  2141                 OP_LOOP( =~ )
  2141 		OP_LOOP( =~ )
  2142                 RETURN (self);
  2142 		RETURN (self);
  2143             }
  2143 	    }
  2144             if (ruleSymbol == @symbol(+)) {
  2144 	    if (ruleSymbol == @symbol(+)) {
  2145                 OP_LOOP_BYTES( += )
  2145 		OP_LOOP_BYTES( += )
  2146                 RETURN (self);
  2146 		RETURN (self);
  2147             }
  2147 	    }
  2148             if (ruleSymbol == @symbol(-)) {
  2148 	    if (ruleSymbol == @symbol(-)) {
  2149                 OP_LOOP_BYTES( -= )
  2149 		OP_LOOP_BYTES( -= )
  2150                 RETURN (self);
  2150 		RETURN (self);
  2151             }
  2151 	    }
  2152         }
  2152 	}
  2153     }
  2153     }
  2154 #undef OP_LOOP_BYTES
  2154 #undef OP_LOOP_BYTES
  2155 #undef OP_LOOP
  2155 #undef OP_LOOP
  2156 %}.
  2156 %}.
  2157     ruleSymbol == #copy ifTrue:[
  2157     ruleSymbol == #copy ifTrue:[
  2158         self from:dstStart to:dstEnd put:sourceByte.
  2158 	self from:dstStart to:dstEnd put:sourceByte.
  2159         ^ self
  2159 	^ self
  2160     ].
  2160     ].
  2161 
  2161 
  2162     dstStart to:dstEnd do:[:dstIdx |
  2162     dstStart to:dstEnd do:[:dstIdx |
  2163         self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:sourceByte).
  2163 	self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:sourceByte).
  2164     ].
  2164     ].
  2165 
  2165 
  2166     "
  2166     "
  2167      #[1 2 3 4 5 6 7 8]
  2167      #[1 2 3 4 5 6 7 8]
  2168         bitBlitBytesFrom:1 to:3 withConstant:1 rule:#bitXor:     
  2168 	bitBlitBytesFrom:1 to:3 withConstant:1 rule:#bitXor:
  2169      #[1 2 3 4 5 6 7 8]
  2169      #[1 2 3 4 5 6 7 8]
  2170         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitXor:
  2170 	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitXor:
  2171      #[1 2 3 4 5 6 7 8]
  2171      #[1 2 3 4 5 6 7 8]
  2172         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitAnd:    
  2172 	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitAnd:
  2173      #[1 2 3 4 5 6 7 8]
  2173      #[1 2 3 4 5 6 7 8]
  2174         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+  
  2174 	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
  2175      #[255 0 0 0 0 0 0 0]
  2175      #[255 0 0 0 0 0 0 0]
  2176         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+     
  2176 	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
  2177      #[1 2 3 4 5 6 7 8]
  2177      #[1 2 3 4 5 6 7 8]
  2178         bitBlitBytesFrom:1 to:4 withConstant:1 rule:#+   
  2178 	bitBlitBytesFrom:1 to:4 withConstant:1 rule:#+
  2179      #[1 2 3 4 5 6 7 8]
  2179      #[1 2 3 4 5 6 7 8]
  2180         bitBlitBytesFrom:1 to:4 withConstant:1 rule:#-       
  2180 	bitBlitBytesFrom:1 to:4 withConstant:1 rule:#-
  2181      #[1 2 3 4 5 6 7 8]
  2181      #[1 2 3 4 5 6 7 8]
  2182         bitBlitBytesFrom:1 to:4 withConstant:1 rule:#copyNot
  2182 	bitBlitBytesFrom:1 to:4 withConstant:1 rule:#copyNot
  2183 
  2183 
  2184      #[1 2 3 4 5 6 7 8]
  2184      #[1 2 3 4 5 6 7 8]
  2185         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
  2185 	bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
  2186     "
  2186     "
  2187 !
  2187 !
  2188 
  2188 
  2189 bitOrBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart 
  2189 bitOrBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart
  2190     "replace bytes in the receiver with the result of a bitOr operation.
  2190     "replace bytes in the receiver with the result of a bitOr operation.
  2191      Warning: this is a destructive operation - elements in the receiver are overwritten."
  2191      Warning: this is a destructive operation - elements in the receiver are overwritten."
  2192 
  2192 
  2193     ^ self bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:#bitOr:
  2193     ^ self bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:#bitOr:
  2194 
  2194 
  2195     "
  2195     "
  2196      #[1 2 3 4 5 6 7 8]
  2196      #[1 2 3 4 5 6 7 8]
  2197 	bitOrBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 
  2197 	bitOrBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1
  2198      #[1 2 3 4 5 6 7 8]
  2198      #[1 2 3 4 5 6 7 8]
  2199 	bitOrBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1
  2199 	bitOrBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1
  2200     "
  2200     "
  2201 
  2201 
  2202 !
  2202 !
  2203 
  2203 
  2204 bitXorBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart 
  2204 bitXorBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart
  2205     "replace bytes in the receiver with the result of an bitXor operation.
  2205     "replace bytes in the receiver with the result of an bitXor operation.
  2206      Warning: this is a destructive operation - elements in the receiver are overwritten."
  2206      Warning: this is a destructive operation - elements in the receiver are overwritten."
  2207 
  2207 
  2208     ^ self bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:#bitXor:
  2208     ^ self bitBlitBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart rule:#bitXor:
  2209 
  2209 
  2210     "
  2210     "
  2211      #[1 2 3 4 5 6 7 8]
  2211      #[1 2 3 4 5 6 7 8]
  2212 	bitXorBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1
  2212 	bitXorBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1
  2213      #[1 2 3 4 5 6 7 8]
  2213      #[1 2 3 4 5 6 7 8]
  2214 	bitXorBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 
  2214 	bitXorBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1
  2215      #[1 2 3 4 5 6 7 8]
  2215      #[1 2 3 4 5 6 7 8]
  2216 	bitXorBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1
  2216 	bitXorBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1
  2217     "
  2217     "
  2218 
  2218 
  2219 !
  2219 !
  2225      using aMapByteArray (if non-nil).
  2225      using aMapByteArray (if non-nil).
  2226      Notice that smalltalk indexing begins at 1; thus the map-index for a byte
  2226      Notice that smalltalk indexing begins at 1; thus the map-index for a byte
  2227      value of n is found in map at:(n + 1).
  2227      value of n is found in map at:(n + 1).
  2228      Output bits are filled left-to right, i.e. the first byte in the input
  2228      Output bits are filled left-to right, i.e. the first byte in the input
  2229      corresponds to the high bit(s) if the first byte in the input.
  2229      corresponds to the high bit(s) if the first byte in the input.
  2230      This method can be used to convert 8-bit image data to mono, 2-bit and 4-bit 
  2230      This method can be used to convert 8-bit image data to mono, 2-bit and 4-bit
  2231      bitmaps.
  2231      bitmaps.
  2232      It can also be used to compress byte-arrays into bitArrays."
  2232      It can also be used to compress byte-arrays into bitArrays."
  2233 
  2233 
  2234 %{  /* NOCONTEXT */
  2234 %{  /* NOCONTEXT */
  2235 
  2235 
  2243     int bitsPerPixel;
  2243     int bitsPerPixel;
  2244     int bits;
  2244     int bits;
  2245     int ncells;
  2245     int ncells;
  2246     unsigned char *map;
  2246     unsigned char *map;
  2247 
  2247 
  2248     if ((__qClass(self) == @global(ByteArray)) 
  2248     if ((__qClass(self) == @global(ByteArray))
  2249      && (__qClass(aByteArray) == @global(ByteArray))
  2249      && (__qClass(aByteArray) == @global(ByteArray))
  2250      && __isSmallInteger(nBitsPerPixel)
  2250      && __isSmallInteger(nBitsPerPixel)
  2251      && __bothSmallInteger(height, width)) {
  2251      && __bothSmallInteger(height, width)) {
  2252 	if ((aMapByteArray != nil)
  2252 	if ((aMapByteArray != nil)
  2253 	 && (__Class(aMapByteArray) == @global(ByteArray))) {
  2253 	 && (__Class(aMapByteArray) == @global(ByteArray))) {
  2359      inBits := #[176 176 176 176 99 99 99 99 176 176 99 99 176 99 176 99].
  2359      inBits := #[176 176 176 176 99 99 99 99 176 176 99 99 176 99 176 99].
  2360      map := ByteArray new:256.
  2360      map := ByteArray new:256.
  2361      map at:176+1 put:1.
  2361      map at:176+1 put:1.
  2362 
  2362 
  2363      outBits := ByteArray new:2.
  2363      outBits := ByteArray new:2.
  2364      inBits compressPixels:1 width:16 height:1 
  2364      inBits compressPixels:1 width:16 height:1
  2365 		    into:outBits mapping:map.
  2365 		    into:outBits mapping:map.
  2366      outBits inspect
  2366      outBits inspect
  2367     "
  2367     "
  2368 
  2368 
  2369     "Example3:
  2369     "Example3:
  2376      inBits := #[176 176 176 176 99 99 99 99 176 176 99 99 176 99 176 99].
  2376      inBits := #[176 176 176 176 99 99 99 99 176 176 99 99 176 99 176 99].
  2377      map := ByteArray new:256.
  2377      map := ByteArray new:256.
  2378      map atAll:(128+1 to:255+1) put:1.
  2378      map atAll:(128+1 to:255+1) put:1.
  2379 
  2379 
  2380      outBits := ByteArray new:2.
  2380      outBits := ByteArray new:2.
  2381      inBits compressPixels:1 width:16 height:1 
  2381      inBits compressPixels:1 width:16 height:1
  2382 		    into:outBits mapping:map.
  2382 		    into:outBits mapping:map.
  2383      outBits inspect
  2383      outBits inspect
  2384     "
  2384     "
  2385 !
  2385 !
  2386 
  2386 
  2421     int bitsPerPixel;
  2421     int bitsPerPixel;
  2422     int bits;
  2422     int bits;
  2423     int ncells;
  2423     int ncells;
  2424     unsigned char *map;
  2424     unsigned char *map;
  2425 
  2425 
  2426     if ((__qClass(self) == @global(ByteArray)) 
  2426     if ((__qClass(self) == @global(ByteArray))
  2427      && (__qClass(aByteArray) == @global(ByteArray))
  2427      && (__qClass(aByteArray) == @global(ByteArray))
  2428      && __isSmallInteger(nBitsPerPixel)
  2428      && __isSmallInteger(nBitsPerPixel)
  2429      && __bothSmallInteger(height, width)) {
  2429      && __bothSmallInteger(height, width)) {
  2430         if ((aMapByteArray != nil)
  2430 	if ((aMapByteArray != nil)
  2431          && (__Class(aMapByteArray) == @global(ByteArray))) {
  2431 	 && (__Class(aMapByteArray) == @global(ByteArray))) {
  2432             map = __ByteArrayInstPtr(aMapByteArray)->ba_element;
  2432 	    map = __ByteArrayInstPtr(aMapByteArray)->ba_element;
  2433         } else {
  2433 	} else {
  2434             map = (unsigned char *)0;
  2434 	    map = (unsigned char *)0;
  2435         }
  2435 	}
  2436 
  2436 
  2437         bitsPerPixel = __intVal(nBitsPerPixel);
  2437 	bitsPerPixel = __intVal(nBitsPerPixel);
  2438         w = __intVal(width);
  2438 	w = __intVal(width);
  2439         h = __intVal(height);
  2439 	h = __intVal(height);
  2440         src = __ByteArrayInstPtr(self)->ba_element;
  2440 	src = __ByteArrayInstPtr(self)->ba_element;
  2441         dst = __ByteArrayInstPtr(aByteArray)->ba_element;
  2441 	dst = __ByteArrayInstPtr(aByteArray)->ba_element;
  2442         switch (bitsPerPixel) {
  2442 	switch (bitsPerPixel) {
  2443             case 1:
  2443 	    case 1:
  2444                 mask = 0x01;
  2444 		mask = 0x01;
  2445                 break;
  2445 		break;
  2446             case 2:
  2446 	    case 2:
  2447                 mask = 0x03;
  2447 		mask = 0x03;
  2448                 break;
  2448 		break;
  2449             case 4:
  2449 	    case 4:
  2450                 mask = 0x0F;
  2450 		mask = 0x0F;
  2451                 break;
  2451 		break;
  2452             case 8:
  2452 	    case 8:
  2453                 mask = 0xFF;
  2453 		mask = 0xFF;
  2454                 break;
  2454 		break;
  2455             default:
  2455 	    default:
  2456                 printf("invalid depth in expandPixels\n");
  2456 		printf("invalid depth in expandPixels\n");
  2457                 goto fail;
  2457 		goto fail;
  2458         }
  2458 	}
  2459         ncells = mask + 1;
  2459 	ncells = mask + 1;
  2460         if (map) {
  2460 	if (map) {
  2461             /*
  2461 	    /*
  2462              * if a map is present, it must have the correct size
  2462 	     * if a map is present, it must have the correct size
  2463              * (i.e. 2 raisedTo:nBitsPerPixel)
  2463 	     * (i.e. 2 raisedTo:nBitsPerPixel)
  2464              */
  2464 	     */
  2465             if ((__qSize(aMapByteArray) - OHDR_SIZE) < ncells) {
  2465 	    if ((__qSize(aMapByteArray) - OHDR_SIZE) < ncells) {
  2466                 printf("invalid map in expandPixels\n");
  2466 		printf("invalid map in expandPixels\n");
  2467                 goto fail;
  2467 		goto fail;
  2468             }
  2468 	    }
  2469         }
  2469 	}
  2470 
  2470 
  2471         bytesPerRow = (w * bitsPerPixel + 7) / 8;
  2471 	bytesPerRow = (w * bitsPerPixel + 7) / 8;
  2472         shift0 = 8 - bitsPerPixel;
  2472 	shift0 = 8 - bitsPerPixel;
  2473         srcBytes = bytesPerRow * h;
  2473 	srcBytes = bytesPerRow * h;
  2474         dstBytes = w * h;
  2474 	dstBytes = w * h;
  2475 
  2475 
  2476         if ((__byteArraySize(self) >= srcBytes)
  2476 	if ((__byteArraySize(self) >= srcBytes)
  2477          && (__byteArraySize(aByteArray) >= dstBytes)) {
  2477 	 && (__byteArraySize(aByteArray) >= dstBytes)) {
  2478             for (hrun=h; hrun; hrun--) {
  2478 	    for (hrun=h; hrun; hrun--) {
  2479                 srcNext = src + bytesPerRow;
  2479 		srcNext = src + bytesPerRow;
  2480                 shift = shift0;
  2480 		shift = shift0;
  2481                 if (map) {
  2481 		if (map) {
  2482                     if (shift0 == 0) {
  2482 		    if (shift0 == 0) {
  2483                         /* translate only */
  2483 			/* translate only */
  2484                         for (wrun=w; wrun; wrun--) {
  2484 			for (wrun=w; wrun; wrun--) {
  2485                             bits = *src++;
  2485 			    bits = *src++;
  2486                             *dst++ = map[bits];
  2486 			    *dst++ = map[bits];
  2487                         }
  2487 			}
  2488                     } else {
  2488 		    } else {
  2489                         for (wrun=w; wrun; wrun--) {
  2489 			for (wrun=w; wrun; wrun--) {
  2490                             if (shift == shift0) {
  2490 			    if (shift == shift0) {
  2491                                 bits = *src++;
  2491 				bits = *src++;
  2492                             }
  2492 			    }
  2493                             *dst++ = map[(bits >> shift) & mask];
  2493 			    *dst++ = map[(bits >> shift) & mask];
  2494                             shift -= bitsPerPixel;
  2494 			    shift -= bitsPerPixel;
  2495                             if (shift < 0) {
  2495 			    if (shift < 0) {
  2496                                 shift = shift0;
  2496 				shift = shift0;
  2497                             }
  2497 			    }
  2498                         }
  2498 			}
  2499                     }
  2499 		    }
  2500                 } else {
  2500 		} else {
  2501                     for (wrun=w; wrun; wrun--) {
  2501 		    for (wrun=w; wrun; wrun--) {
  2502                         if (shift == shift0) {
  2502 			if (shift == shift0) {
  2503                             bits = *src++;
  2503 			    bits = *src++;
  2504                         }
  2504 			}
  2505                         *dst++ = (bits >> shift) & mask;
  2505 			*dst++ = (bits >> shift) & mask;
  2506                         shift -= bitsPerPixel;
  2506 			shift -= bitsPerPixel;
  2507                         if (shift < 0) {
  2507 			if (shift < 0) {
  2508                             shift = shift0;
  2508 			    shift = shift0;
  2509                         }
  2509 			}
  2510                     }
  2510 		    }
  2511                 }
  2511 		}
  2512                 src = srcNext;
  2512 		src = srcNext;
  2513             }
  2513 	    }
  2514             RETURN ( self );
  2514 	    RETURN ( self );
  2515         }
  2515 	}
  2516         printf("buffer size: self:%d expect at least:%d\n", 
  2516 	printf("buffer size: self:%d expect at least:%d\n",
  2517                 __byteArraySize(self), srcBytes);
  2517 		__byteArraySize(self), srcBytes);
  2518         printf("buffer size: arg:%d expect at least:%d\n", 
  2518 	printf("buffer size: arg:%d expect at least:%d\n",
  2519                 __byteArraySize(aByteArray), dstBytes);
  2519 		__byteArraySize(aByteArray), dstBytes);
  2520     }
  2520     }
  2521     printf("invalid args\n");
  2521     printf("invalid args\n");
  2522 
  2522 
  2523 fail: ;
  2523 fail: ;
  2524 %}.
  2524 %}.
  2528      expand 1-bit-per-pixel bitmap into a 1byte-per-pixel byteArray
  2528      expand 1-bit-per-pixel bitmap into a 1byte-per-pixel byteArray
  2529     "
  2529     "
  2530     "
  2530     "
  2531      |inBits outBits|
  2531      |inBits outBits|
  2532 
  2532 
  2533      inBits := #[2r11110000 
  2533      inBits := #[2r11110000
  2534                  2r11001100 
  2534 		 2r11001100
  2535                  2r01010101 
  2535 		 2r01010101
  2536                  2r00001111].
  2536 		 2r00001111].
  2537      outBits := ByteArray new:(8*4).
  2537      outBits := ByteArray new:(8*4).
  2538      inBits expandPixels:1 width:8 height:4
  2538      inBits expandPixels:1 width:8 height:4
  2539                     into:outBits mapping:nil.
  2539 		    into:outBits mapping:nil.
  2540      outBits inspect
  2540      outBits inspect
  2541     "
  2541     "
  2542 
  2542 
  2543     "Example2:
  2543     "Example2:
  2544      expand bit-array into a byteArray, translating 0-bits to 99,
  2544      expand bit-array into a byteArray, translating 0-bits to 99,
  2547     "
  2547     "
  2548      |inBits outBits|
  2548      |inBits outBits|
  2549 
  2549 
  2550      inBits := #[2r11110000 2r11001100].
  2550      inBits := #[2r11110000 2r11001100].
  2551      outBits := ByteArray new:16.
  2551      outBits := ByteArray new:16.
  2552      inBits expandPixels:1 width:16 height:1 
  2552      inBits expandPixels:1 width:16 height:1
  2553                     into:outBits mapping:#[99 176].
  2553 		    into:outBits mapping:#[99 176].
  2554      outBits inspect
  2554      outBits inspect
  2555     "
  2555     "
  2556 
  2556 
  2557     "This Can also be used to extract nibbles ..."
  2557     "This Can also be used to extract nibbles ..."
  2558     "
  2558     "
  2559      |inBits outBits|
  2559      |inBits outBits|
  2560 
  2560 
  2561      inBits := #[ 16r12 16r34 16r56 16r78 16r9A 16rBC 16rDE 16rF0 ]. 
  2561      inBits := #[ 16r12 16r34 16r56 16r78 16r9A 16rBC 16rDE 16rF0 ].
  2562      outBits := ByteArray new:(inBits size * 2).
  2562      outBits := ByteArray new:(inBits size * 2).
  2563      inBits expandPixels:4 width:outBits size height:1 into:outBits mapping:nil.
  2563      inBits expandPixels:4 width:outBits size height:1 into:outBits mapping:nil.
  2564      outBits inspect
  2564      outBits inspect
  2565     "
  2565     "
  2566 
  2566 
  2576     REGISTER unsigned char *dst;
  2576     REGISTER unsigned char *dst;
  2577     REGISTER unsigned long *ldst;
  2577     REGISTER unsigned long *ldst;
  2578     REGISTER int cnt;
  2578     REGISTER int cnt;
  2579 
  2579 
  2580     if (__qClass(self) == @global(ByteArray)) {
  2580     if (__qClass(self) == @global(ByteArray)) {
  2581         cnt = __byteArraySize(self);
  2581 	cnt = __byteArraySize(self);
  2582         dst = __ByteArrayInstPtr(self)->ba_element;
  2582 	dst = __ByteArrayInstPtr(self)->ba_element;
  2583         if (! ((INT)dst & (sizeof(long)-1))) {
  2583 	if (! ((INT)dst & (sizeof(long)-1))) {
  2584             ldst = (unsigned long *)dst;
  2584 	    ldst = (unsigned long *)dst;
  2585             while (cnt >= (sizeof(long))*4) {
  2585 	    while (cnt >= (sizeof(long))*4) {
  2586                 ldst[0] = ~(ldst[0]);
  2586 		ldst[0] = ~(ldst[0]);
  2587                 ldst[1] = ~(ldst[1]);
  2587 		ldst[1] = ~(ldst[1]);
  2588                 ldst[2] = ~(ldst[2]);
  2588 		ldst[2] = ~(ldst[2]);
  2589                 ldst[3] = ~(ldst[3]);
  2589 		ldst[3] = ~(ldst[3]);
  2590                 ldst += 4;
  2590 		ldst += 4;
  2591                 cnt -= (sizeof(long))*4;
  2591 		cnt -= (sizeof(long))*4;
  2592             }
  2592 	    }
  2593             while (cnt >= sizeof(long)) {
  2593 	    while (cnt >= sizeof(long)) {
  2594                 *ldst = ~(*ldst);
  2594 		*ldst = ~(*ldst);
  2595                 ldst++;
  2595 		ldst++;
  2596                 cnt -= sizeof(long);
  2596 		cnt -= sizeof(long);
  2597             }
  2597 	    }
  2598             dst = (unsigned char *)ldst;
  2598 	    dst = (unsigned char *)ldst;
  2599         }
  2599 	}
  2600         while (cnt--) {
  2600 	while (cnt--) {
  2601             *dst = ~(*dst);
  2601 	    *dst = ~(*dst);
  2602             dst++;
  2602 	    dst++;
  2603         }
  2603 	}
  2604         RETURN ( self );
  2604 	RETURN ( self );
  2605     }
  2605     }
  2606 %}.
  2606 %}.
  2607     self bitBlitBytesFrom:1 to:self size withConstant:16rFF rule:#bitXor:
  2607     self bitBlitBytesFrom:1 to:self size withConstant:16rFF rule:#bitXor:
  2608 
  2608 
  2609     "
  2609     "
  2610      #[1 2 3 4 5 6 7 8 9 10] copy invert
  2610      #[1 2 3 4 5 6 7 8 9 10] copy invert
  2611      #[1 2 3 4 5 6 7 8 9 10] copy 
  2611      #[1 2 3 4 5 6 7 8 9 10] copy
  2612         bitBlitBytesFrom:1 to:10 withConstant:16rFF rule:#bitXor: 
  2612 	bitBlitBytesFrom:1 to:10 withConstant:16rFF rule:#bitXor:
  2613     "
  2613     "
  2614 !
  2614 !
  2615 
  2615 
  2616 reverse
  2616 reverse
  2617     "reverse the order of my elements inplace - 
  2617     "reverse the order of my elements inplace -
  2618      WARNING: this is a destructive operation, which modifies the receiver.
  2618      WARNING: this is a destructive operation, which modifies the receiver.
  2619      Written as a primitive for speed on image manipulations (mirror)"
  2619      Written as a primitive for speed on image manipulations (mirror)"
  2620 
  2620 
  2621 %{  /* NOCONTEXT */
  2621 %{  /* NOCONTEXT */
  2622 
  2622 
  2624     REGISTER int cnt;
  2624     REGISTER int cnt;
  2625     REGISTER unsigned t;
  2625     REGISTER unsigned t;
  2626     OBJ cls;
  2626     OBJ cls;
  2627 
  2627 
  2628     if (__qClass(self) == @global(ByteArray)) {
  2628     if (__qClass(self) == @global(ByteArray)) {
  2629         cnt = __byteArraySize(self);
  2629 	cnt = __byteArraySize(self);
  2630         p1 = __ByteArrayInstPtr(self)->ba_element;
  2630 	p1 = __ByteArrayInstPtr(self)->ba_element;
  2631         p2 = p1 + cnt - 1;
  2631 	p2 = p1 + cnt - 1;
  2632 
  2632 
  2633 #if defined(__BSWAP)
  2633 #if defined(__BSWAP)
  2634         /*
  2634 	/*
  2635          * can we use the bswap instruction ?
  2635 	 * can we use the bswap instruction ?
  2636          * notice - not all CPUs have it (the HAS_BSWAP checks this).
  2636 	 * notice - not all CPUs have it (the HAS_BSWAP checks this).
  2637          */
  2637 	 */
  2638         if (__HAS_BSWAP()
  2638 	if (__HAS_BSWAP()
  2639          && ((cnt & 3) == 0)) {
  2639 	 && ((cnt & 3) == 0)) {
  2640             unsigned int *ip1, *ip2;
  2640 	    unsigned int *ip1, *ip2;
  2641 
  2641 
  2642             ip1 = (unsigned int *)p1;
  2642 	    ip1 = (unsigned int *)p1;
  2643             ip2 = (unsigned int *)(p2 - 3);
  2643 	    ip2 = (unsigned int *)(p2 - 3);
  2644 
  2644 
  2645             ip2 -= 7;
  2645 	    ip2 -= 7;
  2646             while (ip1 <= ip2) {
  2646 	    while (ip1 <= ip2) {
  2647                 int t1, t2;
  2647 		int t1, t2;
  2648 
  2648 
  2649                 t1 = ip1[0];
  2649 		t1 = ip1[0];
  2650                 t2 = ip2[7];
  2650 		t2 = ip2[7];
  2651                 ip2[7] = __BSWAP(t1);
  2651 		ip2[7] = __BSWAP(t1);
  2652                 ip1[0] = __BSWAP(t2);
  2652 		ip1[0] = __BSWAP(t2);
  2653 
  2653 
  2654                 t1 = ip1[1];
  2654 		t1 = ip1[1];
  2655                 t2 = ip2[6];
  2655 		t2 = ip2[6];
  2656                 ip2[6] = __BSWAP(t1);
  2656 		ip2[6] = __BSWAP(t1);
  2657                 ip1[1] = __BSWAP(t2);
  2657 		ip1[1] = __BSWAP(t2);
  2658 
  2658 
  2659                 t1 = ip1[2];
  2659 		t1 = ip1[2];
  2660                 t2 = ip2[5];
  2660 		t2 = ip2[5];
  2661                 ip2[5] = __BSWAP(t1);
  2661 		ip2[5] = __BSWAP(t1);
  2662                 ip1[2] = __BSWAP(t2);
  2662 		ip1[2] = __BSWAP(t2);
  2663 
  2663 
  2664                 t1 = ip1[3];
  2664 		t1 = ip1[3];
  2665                 t2 = ip2[4];
  2665 		t2 = ip2[4];
  2666                 ip2[4] = __BSWAP(t1);
  2666 		ip2[4] = __BSWAP(t1);
  2667                 ip1[3] = __BSWAP(t2);
  2667 		ip1[3] = __BSWAP(t2);
  2668 
  2668 
  2669                 ip1 += 4;
  2669 		ip1 += 4;
  2670                 ip2 -= 4;
  2670 		ip2 -= 4;
  2671             }
  2671 	    }
  2672             ip2 += 7;
  2672 	    ip2 += 7;
  2673 
  2673 
  2674             while (ip1 < ip2) {
  2674 	    while (ip1 < ip2) {
  2675                 int t;
  2675 		int t;
  2676 
  2676 
  2677                 t = __BSWAP(*ip1);
  2677 		t = __BSWAP(*ip1);
  2678                 *ip1++ = __BSWAP(*ip2);
  2678 		*ip1++ = __BSWAP(*ip2);
  2679                 *ip2-- = t;
  2679 		*ip2-- = t;
  2680             }                
  2680 	    }
  2681 
  2681 
  2682             if (ip1 == ip2) {
  2682 	    if (ip1 == ip2) {
  2683                 int t;
  2683 		int t;
  2684                 t = *ip1;
  2684 		t = *ip1;
  2685                 t = __BSWAP(t);
  2685 		t = __BSWAP(t);
  2686                 *ip1 = t;
  2686 		*ip1 = t;
  2687             }
  2687 	    }
  2688             RETURN ( self );
  2688 	    RETURN ( self );
  2689         }
  2689 	}
  2690 #endif /* __i386__ && __GNUC__ */
  2690 #endif /* __i386__ && __GNUC__ */
  2691 
  2691 
  2692         p2 -= 7;
  2692 	p2 -= 7;
  2693         while (p1 <= p2) {
  2693 	while (p1 <= p2) {
  2694             t = p1[0];
  2694 	    t = p1[0];
  2695             p1[0] = p2[7];
  2695 	    p1[0] = p2[7];
  2696             p2[7] = t;
  2696 	    p2[7] = t;
  2697 
  2697 
  2698             t = p1[1];
  2698 	    t = p1[1];
  2699             p1[1] = p2[6];
  2699 	    p1[1] = p2[6];
  2700             p2[6] = t;
  2700 	    p2[6] = t;
  2701 
  2701 
  2702             t = p1[2];
  2702 	    t = p1[2];
  2703             p1[2] = p2[5];
  2703 	    p1[2] = p2[5];
  2704             p2[5] = t;
  2704 	    p2[5] = t;
  2705 
  2705 
  2706             t = p1[3];
  2706 	    t = p1[3];
  2707             p1[3] = p2[4];
  2707 	    p1[3] = p2[4];
  2708             p2[4] = t;
  2708 	    p2[4] = t;
  2709 
  2709 
  2710             p1 += 4;
  2710 	    p1 += 4;
  2711             p2 -= 4;
  2711 	    p2 -= 4;
  2712         }
  2712 	}
  2713         p2 += 7;
  2713 	p2 += 7;
  2714 
  2714 
  2715         while (p1 < p2) {
  2715 	while (p1 < p2) {
  2716             t = *p1;
  2716 	    t = *p1;
  2717             *p1++ = *p2;
  2717 	    *p1++ = *p2;
  2718             *p2-- = t;
  2718 	    *p2-- = t;
  2719         }
  2719 	}
  2720         RETURN ( self );
  2720 	RETURN ( self );
  2721     }
  2721     }
  2722 %}.
  2722 %}.
  2723     ^ super reverse
  2723     ^ super reverse
  2724 
  2724 
  2725     "
  2725     "
  2726      #[1 2 3 4 5] reverse      
  2726      #[1 2 3 4 5] reverse
  2727      #[1 2 3 4] reverse       
  2727      #[1 2 3 4] reverse
  2728      #[1 2 3 4 5] reverse       
  2728      #[1 2 3 4 5] reverse
  2729      #[1 2 3 4 5 6] reverse    
  2729      #[1 2 3 4 5 6] reverse
  2730      #[1 2 3 4 5 6 7] reverse    
  2730      #[1 2 3 4 5 6 7] reverse
  2731      #[1 2 3 4 5 6 7 8] reverse        
  2731      #[1 2 3 4 5 6 7 8] reverse
  2732      #[1 2 3 4 5 6 7 8 9] reverse    
  2732      #[1 2 3 4 5 6 7 8 9] reverse
  2733      #[1 2 3 4 5 6 7 8 9 10] reverse    
  2733      #[1 2 3 4 5 6 7 8 9 10] reverse
  2734      #[1 2 3 4 5 6 7 8 9 10 11 12] reverse    
  2734      #[1 2 3 4 5 6 7 8 9 10 11 12] reverse
  2735      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] reverse    
  2735      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] reverse
  2736      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] reverse    
  2736      #[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20] reverse
  2737      (1 to:255) asByteArray reverse   
  2737      (1 to:255) asByteArray reverse
  2738 
  2738 
  2739      1 to:1024 do:[:i|
  2739      1 to:1024 do:[:i|
  2740         |bytes test rBytes|
  2740 	|bytes test rBytes|
  2741 
  2741 
  2742         bytes := ((1 to:i) asArray collect:[:i | i bitAnd:255]) asByteArray.
  2742 	bytes := ((1 to:i) asArray collect:[:i | i bitAnd:255]) asByteArray.
  2743         test := ((i to:1 by:-1) asArray collect:[:i | i bitAnd:255]) asByteArray.
  2743 	test := ((i to:1 by:-1) asArray collect:[:i | i bitAnd:255]) asByteArray.
  2744         rBytes := bytes copy.
  2744 	rBytes := bytes copy.
  2745         rBytes reverse ~= test ifTrue:[
  2745 	rBytes reverse ~= test ifTrue:[
  2746             self halt
  2746 	    self halt
  2747         ].
  2747 	].
  2748         rBytes := bytes copy.
  2748 	rBytes := bytes copy.
  2749         rBytes reverse reverse ~= bytes ifTrue:[
  2749 	rBytes reverse reverse ~= bytes ifTrue:[
  2750             self halt
  2750 	    self halt
  2751         ]
  2751 	]
  2752      ].
  2752      ].
  2753 
  2753 
  2754      Time millisecondsToRun:[
  2754      Time millisecondsToRun:[
  2755         10000000 timesRepeat:[
  2755 	10000000 timesRepeat:[
  2756             #[1 2 3 4 5 6 7 8] reverse 
  2756 	    #[1 2 3 4 5 6 7 8] reverse
  2757         ]
  2757 	]
  2758      ]  
  2758      ]
  2759 
  2759 
  2760      |b|
  2760      |b|
  2761      b := (0 to:255) asByteArray.
  2761      b := (0 to:255) asByteArray.
  2762      Time millisecondsToRun:[
  2762      Time millisecondsToRun:[
  2763         10000000 timesRepeat:[
  2763 	10000000 timesRepeat:[
  2764             b reverse 
  2764 	    b reverse
  2765         ]
  2765 	]
  2766      ]   
  2766      ]
  2767     "
  2767     "
  2768 !
  2768 !
  2769 
  2769 
  2770 swapBytes
  2770 swapBytes
  2771     "swap bytes inplace - 
  2771     "swap bytes inplace -
  2772      written as a primitive for speed on image grabbing (if display order is different)"
  2772      written as a primitive for speed on image grabbing (if display order is different)"
  2773 
  2773 
  2774 %{  /* NOCONTEXT */
  2774 %{  /* NOCONTEXT */
  2775 
  2775 
  2776     REGISTER unsigned char *p;
  2776     REGISTER unsigned char *p;
  2800     }
  2800     }
  2801 %}.
  2801 %}.
  2802     ^ super swapBytes "/ rubbish - there is no one currenly
  2802     ^ super swapBytes "/ rubbish - there is no one currenly
  2803 
  2803 
  2804     "
  2804     "
  2805      #[1 2 3 4 5 6 7 8 9 10] copy swapBytes 
  2805      #[1 2 3 4 5 6 7 8 9 10] copy swapBytes
  2806      #[1 2 3 4 5 6 7 8 9 10 11] copy swapBytes  
  2806      #[1 2 3 4 5 6 7 8 9 10 11] copy swapBytes
  2807     "
  2807     "
  2808 !
  2808 !
  2809 
  2809 
  2810 swapIndex:i1 and:i2
  2810 swapIndex:i1 and:i2
  2811    "spap the bytes with i1 and i2"
  2811    "spap the bytes with i1 and i2"
  2816     unsigned int __i1, __i2;
  2816     unsigned int __i1, __i2;
  2817     int cnt;
  2817     int cnt;
  2818     unsigned int t;
  2818     unsigned int t;
  2819 
  2819 
  2820     if (__qClass(self) == @global(ByteArray) && __bothSmallInteger(i1, i2)) {
  2820     if (__qClass(self) == @global(ByteArray) && __bothSmallInteger(i1, i2)) {
  2821         __i1 = __intVal(i1) - 1;
  2821 	__i1 = __intVal(i1) - 1;
  2822         __i2 = __intVal(i2) - 1;
  2822 	__i2 = __intVal(i2) - 1;
  2823         cnt = __byteArraySize(self);
  2823 	cnt = __byteArraySize(self);
  2824         p = __ByteArrayInstPtr(self)->ba_element;
  2824 	p = __ByteArrayInstPtr(self)->ba_element;
  2825         if (__i1 < cnt && __i2 < cnt) {
  2825 	if (__i1 < cnt && __i2 < cnt) {
  2826             t = p[__i1];
  2826 	    t = p[__i1];
  2827             p[__i1] = p[__i2];
  2827 	    p[__i1] = p[__i2];
  2828             p[__i2] = t;
  2828 	    p[__i2] = t;
  2829         }
  2829 	}
  2830         RETURN ( self );
  2830 	RETURN ( self );
  2831     }
  2831     }
  2832 %}.
  2832 %}.
  2833     ^ super swapIndex:i1 and:i2 "/ rubbish - there is no one currenl
  2833     ^ super swapIndex:i1 and:i2 "/ rubbish - there is no one currenl
  2834 
  2834 
  2835     "
  2835     "
  2836      #[1 2 3 4 5 6 7 8 9 10] copy swapIndex:1 and:10 
  2836      #[1 2 3 4 5 6 7 8 9 10] copy swapIndex:1 and:10
  2837      #[1 2 3 4 5 6 7 8 9 10 11] copy swapIndex:5 and:6  
  2837      #[1 2 3 4 5 6 7 8 9 10 11] copy swapIndex:5 and:6
  2838     "
  2838     "
  2839 
  2839 
  2840 
  2840 
  2841 !
  2841 !
  2842 
  2842 
  2843 swapLongs
  2843 swapLongs
  2844     "swap long bytes inplace 
  2844     "swap long bytes inplace
  2845      - any partial longs at the end are not swapped."
  2845      - any partial longs at the end are not swapped."
  2846 
  2846 
  2847     self swapLongsFrom:1 to:self size
  2847     self swapLongsFrom:1 to:self size
  2848 
  2848 
  2849     "
  2849     "
  2850      #[1 2 3 4 5 6 7 8 9] copy swapLongs 
  2850      #[1 2 3 4 5 6 7 8 9] copy swapLongs
  2851      #[1 2 3 4 5 6 7 8 9 10] copy swapLongs 
  2851      #[1 2 3 4 5 6 7 8 9 10] copy swapLongs
  2852      #[1 2 3 4 5 6 7 8 9 10 11] copy swapLongs  
  2852      #[1 2 3 4 5 6 7 8 9 10 11] copy swapLongs
  2853      #[1 2 3 4 5 6 7 8 9 10 11 12] copy swapLongs  
  2853      #[1 2 3 4 5 6 7 8 9 10 11 12] copy swapLongs
  2854     "
  2854     "
  2855 !
  2855 !
  2856 
  2856 
  2857 swapLongsFrom:startIndex to:endIndex
  2857 swapLongsFrom:startIndex to:endIndex
  2858     "swap longs inplace 
  2858     "swap longs inplace
  2859      - any partial longs at the end are not swapped. 
  2859      - any partial longs at the end are not swapped.
  2860      Swapping is from startIndex to (exclusiv) endIndex;
  2860      Swapping is from startIndex to (exclusiv) endIndex;
  2861      indexing starts at 1."
  2861      indexing starts at 1."
  2862 
  2862 
  2863 %{  /* NOCONTEXT */
  2863 %{  /* NOCONTEXT */
  2864 
  2864 
  2914     }
  2914     }
  2915 %}.
  2915 %}.
  2916     ^ super swapLongsFrom:startIndex to:endIndex "/ rubbish - there is no one currenly
  2916     ^ super swapLongsFrom:startIndex to:endIndex "/ rubbish - there is no one currenly
  2917 
  2917 
  2918     "
  2918     "
  2919      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:3    
  2919      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:3
  2920      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:4    
  2920      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:4
  2921      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:5    
  2921      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:5
  2922      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:6    
  2922      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:6
  2923      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:7    
  2923      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:7
  2924      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:8     
  2924      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:1 to:8
  2925      #[1 2 3 4 5 6 7 8 9 10] copy swapLongsFrom:1 to:11 
  2925      #[1 2 3 4 5 6 7 8 9 10] copy swapLongsFrom:1 to:11
  2926      #[1 2 3 4 5 6 7 8 9 10 11] copy swapLongsFrom:1 to:12  
  2926      #[1 2 3 4 5 6 7 8 9 10 11] copy swapLongsFrom:1 to:12
  2927      #[1 2 3 4 5 6 7 8 9 10 11 12] copy swapLongsFrom:1 to:13 
  2927      #[1 2 3 4 5 6 7 8 9 10 11 12] copy swapLongsFrom:1 to:13
  2928      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:5 to:10   
  2928      #[1 2 3 4 5 6 7 8 9] copy swapLongsFrom:5 to:10
  2929     "
  2929     "
  2930 ! !
  2930 ! !
  2931 
  2931 
  2932 !ByteArray methodsFor:'printing & storing'!
  2932 !ByteArray methodsFor:'printing & storing'!
  2933 
  2933 
  2934 displayString
  2934 displayString
  2935     "return a printed representation of the receiver for displaying"
  2935     "return a printed representation of the receiver for displaying"
  2936 
  2936 
  2937     self class == ByteArray ifTrue:[
  2937     self class == ByteArray ifTrue:[
  2938         ^ self storeString
  2938 	^ self storeString
  2939     ].
  2939     ].
  2940     ^ super displayString
  2940     ^ super displayString
  2941 
  2941 
  2942     "Created: 25.10.1995 / 13:33:26 / cg"
  2942     "Created: 25.10.1995 / 13:33:26 / cg"
  2943     "Modified: 22.4.1996 / 12:54:06 / cg"
  2943     "Modified: 22.4.1996 / 12:54:06 / cg"
  2946 hexPrintOn:aStream
  2946 hexPrintOn:aStream
  2947     "print as hex string, eg: 'FF0243'.
  2947     "print as hex string, eg: 'FF0243'.
  2948      This string can be used in #fromHexString: to recreate the byteArray"
  2948      This string can be used in #fromHexString: to recreate the byteArray"
  2949 
  2949 
  2950     self do:[:byte|
  2950     self do:[:byte|
  2951         byte printOn:aStream base:16 size:2 fill:$0.
  2951 	byte printOn:aStream base:16 size:2 fill:$0.
  2952     ].
  2952     ].
  2953 
  2953 
  2954     "
  2954     "
  2955       #[1 2 3 4 10 17] hexPrintOn:Transcript
  2955       #[1 2 3 4 10 17] hexPrintOn:Transcript
  2956     "
  2956     "
  2957 
  2957 
  2958     "
  2958     "
  2959      |s|
  2959      |s|
  2960      s := String streamContents:[:s | #[1 2 3 4 10 17] hexPrintOn:s].
  2960      s := String streamContents:[:s | #[1 2 3 4 10 17] hexPrintOn:s].
  2961      ByteArray fromHexString:s      
  2961      ByteArray fromHexString:s
  2962     "
  2962     "
  2963 !
  2963 !
  2964 
  2964 
  2965 printOn:aStream
  2965 printOn:aStream
  2966     "append a printed representation to aStream"
  2966     "append a printed representation to aStream"
  2967 
  2967 
  2968     self class == ByteArray ifTrue:[    "/ care for subclasses
  2968     self class == ByteArray ifTrue:[    "/ care for subclasses
  2969         aStream nextPutAll:'#['.
  2969 	aStream nextPutAll:'#['.
  2970         self 
  2970 	self
  2971             do:[:byte | byte printOn:aStream]
  2971 	    do:[:byte | byte printOn:aStream]
  2972             separatedBy:[aStream space].
  2972 	    separatedBy:[aStream space].
  2973         aStream nextPut:$].
  2973 	aStream nextPut:$].
  2974         ^ self
  2974 	^ self
  2975     ].
  2975     ].
  2976     ^ super printOn:aStream
  2976     ^ super printOn:aStream
  2977 
  2977 
  2978     "
  2978     "
  2979      #[1 2 3 4 5] printOn:Transcript
  2979      #[1 2 3 4 5] printOn:Transcript
  2980 
  2980 
  2981 
  2981 
  2982      #[1 2 3 4 5] storeString            
  2982      #[1 2 3 4 5] storeString
  2983      #[1 2 3 4 5] displayString        
  2983      #[1 2 3 4 5] displayString
  2984      #[1 2 3 4 5] printString         
  2984      #[1 2 3 4 5] printString
  2985     "
  2985     "
  2986 
  2986 
  2987     "Modified: / 12.9.1997 / 22:11:33 / cg"
  2987     "Modified: / 12.9.1997 / 22:11:33 / cg"
  2988     "Modified: / 17.3.1999 / 17:01:31 / stefan"
  2988     "Modified: / 17.3.1999 / 17:01:31 / stefan"
  2989 !
  2989 !
  2995 
  2995 
  2996     "
  2996     "
  2997      #[1 2 3 4 5] printOn:Transcript base:2
  2997      #[1 2 3 4 5] printOn:Transcript base:2
  2998      'Hello World' printOn:Transcript base:2
  2998      'Hello World' printOn:Transcript base:2
  2999 
  2999 
  3000      #[1 2 3 4 5] storeString            
  3000      #[1 2 3 4 5] storeString
  3001      #[1 2 3 4 5] displayString        
  3001      #[1 2 3 4 5] displayString
  3002      #[1 2 3 4 5] printString         
  3002      #[1 2 3 4 5] printString
  3003     "
  3003     "
  3004 
  3004 
  3005     "Modified: / 17.3.1999 / 17:01:31 / stefan"
  3005     "Modified: / 17.3.1999 / 17:01:31 / stefan"
  3006     "Modified: / 31.10.2001 / 09:43:56 / cg"
  3006     "Modified: / 31.10.2001 / 09:43:56 / cg"
  3007 !
  3007 !
  3008 
  3008 
  3009 printOn:aStream base:radix showRadix:showRadix
  3009 printOn:aStream base:radix showRadix:showRadix
  3010     "append a printed representation to aStream in the given number base."
  3010     "append a printed representation to aStream in the given number base."
  3011 
  3011 
  3012     self class == ByteArray ifTrue:[    "/ care for subclasses
  3012     self class == ByteArray ifTrue:[    "/ care for subclasses
  3013         aStream nextPutAll:'#['.
  3013 	aStream nextPutAll:'#['.
  3014         self 
  3014 	self
  3015             do:[:byte | byte printOn:aStream base:radix showRadix:showRadix]
  3015 	    do:[:byte | byte printOn:aStream base:radix showRadix:showRadix]
  3016             separatedBy:[aStream space].
  3016 	    separatedBy:[aStream space].
  3017         aStream nextPut:$].
  3017 	aStream nextPut:$].
  3018         ^ self
  3018 	^ self
  3019     ].
  3019     ].
  3020     ^ self printOn:aStream
  3020     ^ self printOn:aStream
  3021 
  3021 
  3022     "
  3022     "
  3023      #[1 2 3 4 5] printOn:Transcript base:2
  3023      #[1 2 3 4 5] printOn:Transcript base:2
  3024      'Hello World' printOn:Transcript base:2
  3024      'Hello World' printOn:Transcript base:2
  3025 
  3025 
  3026      #[1 2 3 4 5] storeString            
  3026      #[1 2 3 4 5] storeString
  3027      #[1 2 3 4 5] displayString        
  3027      #[1 2 3 4 5] displayString
  3028      #[1 2 3 4 5] printString         
  3028      #[1 2 3 4 5] printString
  3029     "
  3029     "
  3030 
  3030 
  3031     "Modified: / 12.9.1997 / 22:11:33 / cg"
  3031     "Modified: / 12.9.1997 / 22:11:33 / cg"
  3032     "Modified: / 17.3.1999 / 17:01:31 / stefan"
  3032     "Modified: / 17.3.1999 / 17:01:31 / stefan"
  3033     "Created: / 31.10.2001 / 09:43:41 / cg"
  3033     "Created: / 31.10.2001 / 09:43:41 / cg"
  3035 
  3035 
  3036 storeArrayElementOn:aStream
  3036 storeArrayElementOn:aStream
  3037     "Store as element of an array. Omit the leading '#'"
  3037     "Store as element of an array. Omit the leading '#'"
  3038 
  3038 
  3039     self class == ByteArray ifTrue:[    "/ care for subclasses
  3039     self class == ByteArray ifTrue:[    "/ care for subclasses
  3040         aStream nextPut:$[.
  3040 	aStream nextPut:$[.
  3041         self 
  3041 	self
  3042             do:[:byte | byte storeOn:aStream]
  3042 	    do:[:byte | byte storeOn:aStream]
  3043             separatedBy:[aStream space].
  3043 	    separatedBy:[aStream space].
  3044         aStream nextPut:$].
  3044 	aStream nextPut:$].
  3045         ^ self
  3045 	^ self
  3046     ].
  3046     ].
  3047     super storeArrayElementOn:aStream
  3047     super storeArrayElementOn:aStream
  3048 
  3048 
  3049     "
  3049     "
  3050      #[1 2 3 4 5] storeOn:Transcript   
  3050      #[1 2 3 4 5] storeOn:Transcript
  3051      #[1 2 3 4 5] storeArrayElementOn:Transcript   
  3051      #[1 2 3 4 5] storeArrayElementOn:Transcript
  3052 
  3052 
  3053      #[1 2 3 4 5] storeString            
  3053      #[1 2 3 4 5] storeString
  3054      #[1 2 3 4 5] displayString        
  3054      #[1 2 3 4 5] displayString
  3055      #[1 2 3 4 5] printString         
  3055      #[1 2 3 4 5] printString
  3056     "
  3056     "
  3057 
  3057 
  3058     "Modified: 12.9.1997 / 22:11:33 / cg"
  3058     "Modified: 12.9.1997 / 22:11:33 / cg"
  3059 !
  3059 !
  3060 
  3060 
  3062     "append a printed representation from which the receiver can be
  3062     "append a printed representation from which the receiver can be
  3063      reconstructed to aStream. (reimplemented to make it look better)"
  3063      reconstructed to aStream. (reimplemented to make it look better)"
  3064 
  3064 
  3065     self class == ByteArray ifTrue:[    "/ care for subclasses
  3065     self class == ByteArray ifTrue:[    "/ care for subclasses
  3066 	aStream nextPutAll:'#['.
  3066 	aStream nextPutAll:'#['.
  3067 	self 
  3067 	self
  3068 	    do:[:byte | byte storeOn:aStream]
  3068 	    do:[:byte | byte storeOn:aStream]
  3069 	    separatedBy:[aStream space].
  3069 	    separatedBy:[aStream space].
  3070 	aStream nextPutAll:']'.
  3070 	aStream nextPutAll:']'.
  3071 	^ self
  3071 	^ self
  3072     ].
  3072     ].
  3073     ^ super storeOn:aStream
  3073     ^ super storeOn:aStream
  3074 
  3074 
  3075     "
  3075     "
  3076      #[1 2 3 4 5] storeOn:Transcript   
  3076      #[1 2 3 4 5] storeOn:Transcript
  3077 
  3077 
  3078      #[1 2 3 4 5] storeString            
  3078      #[1 2 3 4 5] storeString
  3079      #[1 2 3 4 5] displayString        
  3079      #[1 2 3 4 5] displayString
  3080      #[1 2 3 4 5] printString         
  3080      #[1 2 3 4 5] printString
  3081     "
  3081     "
  3082 
  3082 
  3083     "Modified: 12.9.1997 / 22:11:33 / cg"
  3083     "Modified: 12.9.1997 / 22:11:33 / cg"
  3084 ! !
  3084 ! !
  3085 
  3085 
  3086 !ByteArray methodsFor:'queries'!
  3086 !ByteArray methodsFor:'queries'!
  3087 
  3087 
  3088 max
  3088 max
  3089     "return the maximum value in the receiver -
  3089     "return the maximum value in the receiver -
  3090      redefined to speedup image processing and sound-player 
  3090      redefined to speedup image processing and sound-player
  3091      (which need a fast method for this on byteArrays)"
  3091      (which need a fast method for this on byteArrays)"
  3092 
  3092 
  3093 %{  /* NOCONTEXT */
  3093 %{  /* NOCONTEXT */
  3094 
  3094 
  3095     REGISTER unsigned char *cp;
  3095     REGISTER unsigned char *cp;
  3116     }
  3116     }
  3117 %}.
  3117 %}.
  3118     ^ super max
  3118     ^ super max
  3119 
  3119 
  3120     "
  3120     "
  3121      #[1 2 3 1 2 3 1 2 19] max 
  3121      #[1 2 3 1 2 3 1 2 19] max
  3122     "
  3122     "
  3123 !
  3123 !
  3124 
  3124 
  3125 usageCounts
  3125 usageCounts
  3126     "return an array filled with value-counts -
  3126     "return an array filled with value-counts -
  3166 %}
  3166 %}
  3167 .
  3167 .
  3168     self primitiveFailed
  3168     self primitiveFailed
  3169 
  3169 
  3170     "
  3170     "
  3171      #[1 2 3 1 2 3 1 2 250 251 250 251 255] usageCounts 
  3171      #[1 2 3 1 2 3 1 2 250 251 250 251 255] usageCounts
  3172     "
  3172     "
  3173 !
  3173 !
  3174 
  3174 
  3175 usedValues
  3175 usedValues
  3176     "return a new ByteArray with all used values (actually a kind of Set);
  3176     "return a new ByteArray with all used values (actually a kind of Set);
  3177      This is needed specially in the bitmap/Imageclasses to find used colors 
  3177      This is needed specially in the bitmap/Imageclasses to find used colors
  3178      of an image."
  3178      of an image."
  3179 
  3179 
  3180 %{  /* STACK: 400 */
  3180 %{  /* STACK: 400 */
  3181 
  3181 
  3182     REGISTER unsigned char *cp;
  3182     REGISTER unsigned char *cp;
  3233 	/* create ByteArray of used values */
  3233 	/* create ByteArray of used values */
  3234 	result = __BYTEARRAY_UNINITIALIZED_NEW_INT(len);
  3234 	result = __BYTEARRAY_UNINITIALIZED_NEW_INT(len);
  3235 	if (result) {
  3235 	if (result) {
  3236 	    cp = __ByteArrayInstPtr(result)->ba_element;
  3236 	    cp = __ByteArrayInstPtr(result)->ba_element;
  3237 	    for (len=0; len < 256; len++) {
  3237 	    for (len=0; len < 256; len++) {
  3238 		if (f.flags[len]) 
  3238 		if (f.flags[len])
  3239 		    *cp++ = len;
  3239 		    *cp++ = len;
  3240 	    }
  3240 	    }
  3241 	    RETURN ( result );
  3241 	    RETURN ( result );
  3242 	}
  3242 	}
  3243     }
  3243     }
  3244 %}.
  3244 %}.
  3245     ^ self asIdentitySet asByteArray
  3245     ^ self asIdentitySet asByteArray
  3246 
  3246 
  3247     "
  3247     "
  3248      #[1 2 3 1 2 3 1 2 3 1 2 3 4 5 6 4 5 6] usedValues 
  3248      #[1 2 3 1 2 3 1 2 3 1 2 3 4 5 6 4 5 6] usedValues
  3249     "
  3249     "
  3250 ! !
  3250 ! !
  3251 
  3251 
  3252 !ByteArray methodsFor:'searching'!
  3252 !ByteArray methodsFor:'searching'!
  3253 
  3253 
  3297     }
  3297     }
  3298 %}.
  3298 %}.
  3299     ^ super indexOf:aByte startingAt:start
  3299     ^ super indexOf:aByte startingAt:start
  3300 
  3300 
  3301     "
  3301     "
  3302      #[1 2 3 4 5 6 7 8 9 0 1 2 3 4 5] indexOf:0 
  3302      #[1 2 3 4 5 6 7 8 9 0 1 2 3 4 5] indexOf:0
  3303     "
  3303     "
  3304 ! !
  3304 ! !
  3305 
  3305 
  3306 !ByteArray methodsFor:'testing'!
  3306 !ByteArray methodsFor:'testing'!
  3307 
  3307 
  3317 isLiteral
  3317 isLiteral
  3318     "return true, if the receiver can be used as a literal constant in ST syntax
  3318     "return true, if the receiver can be used as a literal constant in ST syntax
  3319      (i.e. can be used in constant arrays)"
  3319      (i.e. can be used in constant arrays)"
  3320 
  3320 
  3321     "/ no, simply returning true here is a mistake:
  3321     "/ no, simply returning true here is a mistake:
  3322     "/ it could be a subclass of ByteArray 
  3322     "/ it could be a subclass of ByteArray
  3323     "/ (of which the compiler does not know at all ...)
  3323     "/ (of which the compiler does not know at all ...)
  3324 
  3324 
  3325     ^ self class == ByteArray
  3325     ^ self class == ByteArray
  3326 
  3326 
  3327     "Modified: 22.4.1996 / 12:55:30 / cg"
  3327     "Modified: 22.4.1996 / 12:55:30 / cg"
  3335 ! !
  3335 ! !
  3336 
  3336 
  3337 !ByteArray class methodsFor:'documentation'!
  3337 !ByteArray class methodsFor:'documentation'!
  3338 
  3338 
  3339 version
  3339 version
  3340     ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.168 2005-07-07 15:01:51 cg Exp $'
  3340     ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.169 2005-07-08 14:00:04 cg Exp $'
  3341 ! !
  3341 ! !