ByteArray.st
changeset 5439 956c8095c4ff
parent 5425 9a2bb3d1cc82
child 5468 96e2cb78498f
equal deleted inserted replaced
5438:00e3c22156c3 5439:956c8095c4ff
   358 
   358 
   359     "Modified: 19.4.1996 / 11:14:40 / cg"
   359     "Modified: 19.4.1996 / 11:14:40 / cg"
   360 !
   360 !
   361 
   361 
   362 bitAt:index
   362 bitAt:index
   363     "return the bit at index" 
   363     "return the bit at index (1 based index)" 
       
   364 
       
   365     |byteIndex bitIndex0 byte|
   364 
   366 
   365 %{  /* NOCONTEXT */
   367 %{  /* NOCONTEXT */
   366 
   368 
   367     REGISTER int indx;
   369     REGISTER int indx;
   368     REGISTER int byte;
   370     REGISTER int byte;
   369     int nIndex;
   371     int nIndex;
   370     REGISTER OBJ slf;
   372     REGISTER OBJ slf;
   371     REGISTER OBJ cls;
   373     REGISTER OBJ cls;
   372 
   374 
   373     if (__isSmallInteger(index)) {
   375     if (__isSmallInteger(index)) {
   374 	indx = __intVal(index) - 1;
   376         indx = __intVal(index) - 1;
   375 	slf = self;
   377         slf = self;
   376 
   378 
   377 	byte = indx / 8;
   379         byte = indx / 8;
   378 	indx = indx % 8;
   380         indx = indx % 8;
   379 
   381 
   380 	if ((cls = __qClass(slf)) != @global(ByteArray)) {
   382         if ((cls = __qClass(slf)) != @global(ByteArray)) {
   381 	    if (indx < 0) goto badIndex;
   383             if (indx < 0) goto badIndex;
   382 	    byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   384             byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   383 	}
   385         }
   384 	nIndex = __byteArraySize(slf);
   386         nIndex = __byteArraySize(slf);
   385 	if ((unsigned)byte < (unsigned)nIndex) {
   387         if ((unsigned)byte < (unsigned)nIndex) {
   386 	    RETURN ( __MKSMALLINT((__ByteArrayInstPtr(slf)->ba_element[byte] & (1 << indx)) != 0) );
   388             RETURN ( __MKSMALLINT((__ByteArrayInstPtr(slf)->ba_element[byte] & (1 << indx)) != 0) );
   387 	}
   389         }
   388     }
   390     }
   389 badIndex: ;
   391 badIndex: ;
   390 %}.
   392 %}.
   391     ^ self primitiveFailed
   393     byteIndex := ((index-1) // 8) + 1.
       
   394     bitIndex0 := ((index-1) \\ 8).
       
   395     byte := self at:byteIndex.
       
   396     ^  byte bitTest:(1 bitShift:bitIndex0).
   392 
   397 
   393    "
   398    "
   394      #[ 1 1 1 1 ] bitAt:9
   399      #[ 1 1 1 1 ] bitAt:9
   395      #[ 1 1 1 1 ] bitAt:11
   400      #[ 1 1 1 1 ] bitAt:11
   396      #[ 2 2 2 2 ] bitAt:10
   401      #[ 2 2 2 2 ] bitAt:10
   398 
   403 
   399 
   404 
   400 
   405 
   401 !
   406 !
   402 
   407 
   403 bitSetAt:index
   408 bitClearAt:index
   404     "set the bit at index (index starts with 1)" 
   409     "clear the bit at index (index starts with 1)" 
       
   410 
       
   411     |byteIndex bitIndex0 byte|
   405 
   412 
   406 %{  /* NOCONTEXT */
   413 %{  /* NOCONTEXT */
   407 
   414 
   408     REGISTER int indx;
   415     REGISTER int indx;
   409     REGISTER int byte;
   416     REGISTER int byte;
   410     int nIndex;
   417     int nIndex;
   411     REGISTER OBJ slf;
   418     REGISTER OBJ slf;
   412     REGISTER OBJ cls;
   419     REGISTER OBJ cls;
   413 
   420 
   414     if (__isSmallInteger(index)) {
   421     if (0 /* __isSmallInteger(index) */) {
   415 	indx = __intVal(index) - 1;
   422         indx = __intVal(index) - 1;
   416 	slf = self;
   423         slf = self;
   417 
   424 
   418 	byte = indx / 8;
   425         byte = indx / 8;
   419 	indx = indx % 8;
   426         indx = indx % 8;
   420 
   427 
   421 	if ((cls = __qClass(slf)) != @global(ByteArray)) {
   428         if ((cls = __qClass(slf)) != @global(ByteArray)) {
   422 	    if (indx < 0) goto badIndex;
   429             if (indx < 0) goto badIndex;
   423 	    byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   430             byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   424 	}
   431         }
   425 	nIndex = __byteArraySize(slf);
   432         nIndex = __byteArraySize(slf);
   426 	if ((unsigned)byte < (unsigned)nIndex) {
   433         if ((unsigned)byte < (unsigned)nIndex) {
   427 	    __ByteArrayInstPtr(slf)->ba_element[byte] |= (1 << indx);
   434             __ByteArrayInstPtr(slf)->ba_element[byte] &= ~(1 << indx);
   428 	    RETURN (slf);
   435             RETURN (slf);
   429 	}
   436         }
   430     }
   437     }
   431 badIndex: ;
   438 badIndex: ;
   432 %}.
   439 %}.
   433     ^ self primitiveFailed
   440     byteIndex := ((index-1) // 8) + 1.
   434 
   441     bitIndex0 := ((index-1) \\ 8).
       
   442     byte := self at:byteIndex.
       
   443     byte := byte bitClear:(1 bitShift:bitIndex0).
       
   444     self at:byteIndex put:byte.
       
   445 
       
   446     "
       
   447      #[0 0 0 0] copy bitClearAt:1  
       
   448      #[0 0 0 0] copy bitClearAt:7  
       
   449      #[0 0 0 0] copy bitClearAt:8  
       
   450      #[0 0 0 0] copy bitClearAt:9  
       
   451     "
   435    "
   452    "
   436      #[ 0 0 0 0 ] bitSetAt:1  
   453      #[ 0 0 0 0 ] bitSetAt:1  
   437      #[ 0 0 0 0 ] bitSetAt:4  
   454      #[ 0 0 0 0 ] bitSetAt:4  
   438      #[ 0 0 0 0 ] bitSetAt:8  
   455      #[ 0 0 0 0 ] bitSetAt:8  
   439      #[ 0 0 0 0 ] bitSetAt:9  
   456      #[ 0 0 0 0 ] bitSetAt:9  
   440      #[ 0 0 0 0 ] bitSetAt:10
   457      #[ 0 0 0 0 ] bitSetAt:10 
   441      #[ 0 0 0 0 ] bitSetAt:11
   458      #[ 0 0 0 0 ] bitSetAt:11 
       
   459    "
       
   460 
       
   461 
       
   462 
       
   463 !
       
   464 
       
   465 bitSetAt:index
       
   466     "set the bit at index (index starts with 1)" 
       
   467 
       
   468     |byteIndex bitIndex0 byte|
       
   469 
       
   470 %{  /* NOCONTEXT */
       
   471 
       
   472     REGISTER int indx;
       
   473     REGISTER int byte;
       
   474     int nIndex;
       
   475     REGISTER OBJ slf;
       
   476     REGISTER OBJ cls;
       
   477 
       
   478     if (0 /* __isSmallInteger(index) */) {
       
   479         indx = __intVal(index) - 1;
       
   480         slf = self;
       
   481 
       
   482         byte = indx / 8;
       
   483         indx = indx % 8;
       
   484 
       
   485         if ((cls = __qClass(slf)) != @global(ByteArray)) {
       
   486             if (indx < 0) goto badIndex;
       
   487             byte += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
       
   488         }
       
   489         nIndex = __byteArraySize(slf);
       
   490         if ((unsigned)byte < (unsigned)nIndex) {
       
   491             __ByteArrayInstPtr(slf)->ba_element[byte] |= (1 << indx);
       
   492             RETURN (slf);
       
   493         }
       
   494     }
       
   495 badIndex: ;
       
   496 %}.
       
   497     byteIndex := ((index-1) // 8) + 1.
       
   498     bitIndex0 := ((index-1) \\ 8).
       
   499     byte := self at:byteIndex.
       
   500     byte := byte bitOr:(1 bitShift:bitIndex0).
       
   501     self at:byteIndex put:byte.
       
   502 
       
   503     "
       
   504      #[0 0 0 0] copy bitSetAt:1  
       
   505      #[0 0 0 0] copy bitSetAt:7  
       
   506      #[0 0 0 0] copy bitSetAt:8  
       
   507      #[0 0 0 0] copy bitSetAt:9  
       
   508     "
       
   509    "
       
   510      #[ 0 0 0 0 ] bitSetAt:1  
       
   511      #[ 0 0 0 0 ] bitSetAt:4  
       
   512      #[ 0 0 0 0 ] bitSetAt:8  
       
   513      #[ 0 0 0 0 ] bitSetAt:9  
       
   514      #[ 0 0 0 0 ] bitSetAt:10 
       
   515      #[ 0 0 0 0 ] bitSetAt:11 
   442    "
   516    "
   443 
   517 
   444 
   518 
   445 
   519 
   446 !
   520 !
   520 %{  /* NOCONTEXT */
   594 %{  /* NOCONTEXT */
   521 
   595 
   522     REGISTER int indx;
   596     REGISTER int indx;
   523     int nIndex;
   597     int nIndex;
   524     union {
   598     union {
   525 	unsigned char u_char[4];
   599         unsigned char u_char[4];
   526 	unsigned int u_uint;
   600         unsigned int u_uint;
   527     } val;
   601     } val;
   528     OBJ cls;
   602     OBJ cls;
   529     unsigned char *byteP;
   603     unsigned char *byteP;
   530 
   604 
   531     if (__isSmallInteger(index)) {
   605     if (__isSmallInteger(index)) {
   532 	if (__isSmallInteger(value)) {
   606         if (__isSmallInteger(value)) {
   533 	    val.u_uint = __intVal(value);
   607             val.u_uint = __intVal(value);
   534 	} else {
   608         } else {
   535 	    val.u_uint = __longIntVal(value);
   609             val.u_uint = __longIntVal(value);
   536 	    if (val.u_uint == 0) goto error;
   610             if (val.u_uint == 0) goto error;
   537 	}
   611         }
   538 
   612 
   539 	indx = __intVal(index);
   613         indx = __intVal(index);
   540 	if (indx > 0) {
   614         if (indx > 0) {
   541 	    if ((cls = __qClass(self)) != @global(ByteArray))
   615             if ((cls = __qClass(self)) != @global(ByteArray))
   542 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   616                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   543 	    nIndex = __qSize(self) - OHDR_SIZE;
   617             nIndex = __qSize(self) - OHDR_SIZE;
   544 	    if ((indx+3) <= nIndex) {
   618             if ((indx+3) <= nIndex) {
   545 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   619                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   546 #if defined(i386) || defined(UNALIGNED_FETCH_OK)
   620 #if defined(i386) || defined(UNALIGNED_FETCH_OK)
   547 		((unsigned int *)byteP)[0] = val.u_uint; 
   621                 ((unsigned int *)byteP)[0] = val.u_uint; 
   548 #else
   622 #else
   549 		if (((unsigned INT)byteP & 3) == 0) {
   623                 if (((unsigned INT)byteP & 3) == 0) {
   550 		    ((unsigned int *)byteP)[0] = val.u_uint; 
   624                     ((unsigned int *)byteP)[0] = val.u_uint; 
   551 		} else {
   625                 } else {
   552 		    byteP[0] = val.u_char[0];
   626                     byteP[0] = val.u_char[0];
   553 		    byteP[1] = val.u_char[1];
   627                     byteP[1] = val.u_char[1];
   554 		    byteP[2] = val.u_char[2];
   628                     byteP[2] = val.u_char[2];
   555 		    byteP[3] = val.u_char[3];
   629                     byteP[3] = val.u_char[3];
   556 		}
   630                 }
   557 #endif
   631 #endif
   558 		RETURN ( value );
   632                 RETURN ( value );
   559 	    }
   633             }
   560 	}
   634         }
   561     }
   635     }
   562   error: ;
   636   error: ;
   563 %}.
   637 %}.
   564     ^ SubscriptOutOfBoundsSignal raise.
   638     ^ super doubleWordAt:index put:value.
   565 
   639 
   566     "
   640     "
   567      |b|
   641      |b|
   568      b := ByteArray new:4.
   642      b := ByteArray new:4.
   569      b doubleWordAt:1 put:16r04030201.
   643      b doubleWordAt:1 put:16r04030201.
   586     int val;
   660     int val;
   587     OBJ cls;
   661     OBJ cls;
   588     unsigned char *byteP;
   662     unsigned char *byteP;
   589 
   663 
   590     if (__isSmallInteger(index)) {
   664     if (__isSmallInteger(index)) {
   591 	if (__isSmallInteger(value)) {
   665         if (__isSmallInteger(value)) {
   592 	    val = __intVal(value);
   666             val = __intVal(value);
   593 	} else {
   667         } else {
   594 	    val = __longIntVal(value);
   668             val = __longIntVal(value);
   595 	    if (val == 0) goto error;
   669             if (val == 0) goto error;
   596 	}
   670         }
   597 	indx = __intVal(index);
   671         indx = __intVal(index);
   598 	if (indx > 0) {
   672         if (indx > 0) {
   599 	    if ((cls = __qClass(self)) != @global(ByteArray))
   673             if ((cls = __qClass(self)) != @global(ByteArray))
   600 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   674                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   601 	    nIndex = __qSize(self) - OHDR_SIZE;
   675             nIndex = __qSize(self) - OHDR_SIZE;
   602 	    if ((indx+3) <= nIndex) {
   676             if ((indx+3) <= nIndex) {
   603 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   677                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   604 		if (msb == true) {
   678                 if (msb == true) {
   605 		    /*
   679                     /*
   606 		     * most significant byte first (i.e sparc order)
   680                      * most significant byte first (i.e sparc order)
   607 		     */
   681                      */
   608 #if defined(__MSBFIRST) ||defined(sparc)
   682 #if defined(__MSBFIRST) ||defined(sparc)
   609 		    if (((INT)byteP & 3) == 0) {
   683                     if (((INT)byteP & 3) == 0) {
   610 			((int *)byteP)[0] = val; 
   684                         ((int *)byteP)[0] = val; 
   611 		    } else 
   685                     } else 
   612 #endif
   686 #endif
   613 		    {
   687                     {
   614 			byteP[3] = val & 0xFF;
   688                         byteP[3] = val & 0xFF;
   615 			val >>= 8;
   689                         val >>= 8;
   616 			byteP[2] = val & 0xFF;
   690                         byteP[2] = val & 0xFF;
   617 			val >>= 8;
   691                         val >>= 8;
   618 			byteP[1] = val & 0xFF;
   692                         byteP[1] = val & 0xFF;
   619 			val >>= 8;
   693                         val >>= 8;
   620 			byteP[0] = val & 0xFF;
   694                         byteP[0] = val & 0xFF;
   621 		    }
   695                     }
   622 		} else {
   696                 } else {
   623 		    /*
   697                     /*
   624 		     * least significant byte first (i.e i386/alpha order)
   698                      * least significant byte first (i.e i386/alpha order)
   625 		     */
   699                      */
   626 #if defined(i386) || (defined(__LSBFIRST) && defined(UNALIGNED_FETCH_OK))
   700 #if defined(i386) || (defined(__LSBFIRST) && defined(UNALIGNED_FETCH_OK))
   627 		    ((int *)byteP)[0] = val;
   701                     ((int *)byteP)[0] = val;
   628 #else
   702 #else
   629 # if defined(__LSBFIRST)
   703 # if defined(__LSBFIRST)
   630 		    if (((unsigned INT)byteP & 3) == 0) {
   704                     if (((unsigned INT)byteP & 3) == 0) {
   631 			((int *)byteP)[0] = val; 
   705                         ((int *)byteP)[0] = val; 
   632 		    } else 
   706                     } else 
   633 # endif
   707 # endif
   634 		    {
   708                     {
   635 			byteP[0] = val & 0xFF;
   709                         byteP[0] = val & 0xFF;
   636 			val >>= 8;
   710                         val >>= 8;
   637 			byteP[1] = val & 0xFF;
   711                         byteP[1] = val & 0xFF;
   638 			val >>= 8;
   712                         val >>= 8;
   639 			byteP[2] = val & 0xFF;
   713                         byteP[2] = val & 0xFF;
   640 			val >>= 8;
   714                         val >>= 8;
   641 			byteP[3] = val & 0xFF;
   715                         byteP[3] = val & 0xFF;
   642 		    }
   716                     }
   643 #endif
   717 #endif
   644 		}
   718                 }
   645 		RETURN ( value );
   719                 RETURN ( value );
   646 	    }
   720             }
   647 	}
   721         }
   648     }
   722     }
   649   error: ;
   723   error: ;
   650 %}.
   724 %}.
   651     ^ SubscriptOutOfBoundsSignal raise.
   725     ^ super doubleWordAt:index put:value MSB:msb
   652 
   726 
   653     "
   727     "
   654      |b|
   728      |b|
   655      b := ByteArray new:8.
   729      b := ByteArray new:8.
   656      b doubleWordAt:1 put:16r04030201 MSB:true.
   730      b doubleWordAt:1 put:16r04030201 MSB:true.
   667 %{  /* NOCONTEXT */
   741 %{  /* NOCONTEXT */
   668 
   742 
   669     REGISTER int indx;
   743     REGISTER int indx;
   670     int nIndex;
   744     int nIndex;
   671     union {
   745     union {
   672 	unsigned char u_char[2];
   746         unsigned char u_char[2];
   673 	unsigned short u_ushort;
   747         unsigned short u_ushort;
   674     } val;
   748     } val;
   675     OBJ cls;
   749     OBJ cls;
   676     unsigned char *byteP;
   750     unsigned char *byteP;
   677 
   751 
   678     if (__isSmallInteger(index)) {
   752     if (__isSmallInteger(index)) {
   679 	indx = __intVal(index);
   753         indx = __intVal(index);
   680 	if (indx > 0) {
   754         if (indx > 0) {
   681 	    if ((cls = __qClass(self)) != @global(ByteArray))
   755             if ((cls = __qClass(self)) != @global(ByteArray))
   682 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   756                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   683 	    nIndex = __byteArraySize(self);
   757             nIndex = __byteArraySize(self);
   684 	    if ((indx+1) <= nIndex) {
   758             if ((indx+1) <= nIndex) {
   685 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   759                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   686 #if defined(i386) || defined(UNALIGNED_FETCH_OK)
   760 #if defined(i386) || defined(UNALIGNED_FETCH_OK)
   687 		val.u_ushort = ((unsigned short *)byteP)[0]; 
   761                 val.u_ushort = ((unsigned short *)byteP)[0]; 
   688 #else
   762 #else
   689 		/*
   763                 /*
   690 		 * mhmh to be measured:
   764                  * mhmh to be measured:
   691 		 *   the if may hurt more than the additional
   765                  *   the if may hurt more than the additional
   692 		 *   memory cycles on some machines ...
   766                  *   memory cycles on some machines ...
   693 		 */
   767                  */
   694 		if (((INT)byteP & 1) == 0) {
   768                 if (((INT)byteP & 1) == 0) {
   695 		    /* aligned */
   769                     /* aligned */
   696 		    val.u_ushort = ((unsigned short *)byteP)[0]; 
   770                     val.u_ushort = ((unsigned short *)byteP)[0]; 
   697 		} else {
   771                 } else {
   698 		    val.u_char[0] = byteP[0];
   772                     val.u_char[0] = byteP[0];
   699 		    val.u_char[1] = byteP[1];
   773                     val.u_char[1] = byteP[1];
   700 		}
   774                 }
   701 #endif
   775 #endif
   702 		RETURN ( __MKSMALLINT(val.u_ushort) );
   776                 RETURN ( __MKSMALLINT(val.u_ushort) );
   703 	    }
   777             }
   704 	}
   778         }
   705     }
   779     }
   706 %}.
   780 %}.
   707     ^ SubscriptOutOfBoundsSignal raise.
   781     ^ super wordAt:index
   708 !
   782 !
   709 
   783 
   710 wordAt:index MSB:msb
   784 wordAt:index MSB:msb
   711     "return the 2-bytes starting at index as an (unsigned) Integer.
   785     "return the 2-bytes starting at index as an (unsigned) Integer.
   712      The value is retrieved MSB (high 8 bits at lower index) if msb is true;
   786      The value is retrieved MSB (high 8 bits at lower index) if msb is true;
   720     int val;
   794     int val;
   721     OBJ cls;
   795     OBJ cls;
   722     unsigned char *byteP;
   796     unsigned char *byteP;
   723 
   797 
   724     if (__isSmallInteger(index)) {
   798     if (__isSmallInteger(index)) {
   725 	indx = __intVal(index);
   799         indx = __intVal(index);
   726 	if (indx > 0) {
   800         if (indx > 0) {
   727 	    if ((cls = __qClass(self)) != @global(ByteArray))
   801             if ((cls = __qClass(self)) != @global(ByteArray))
   728 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   802                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   729 	    nIndex = __byteArraySize(self);
   803             nIndex = __byteArraySize(self);
   730 	    if ((indx+1) <= nIndex) {
   804             if ((indx+1) <= nIndex) {
   731 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   805                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   732 		if (msb == true) {
   806                 if (msb == true) {
   733 		    /*
   807                     /*
   734 		     * most significant byte first (i.e sparc order)
   808                      * most significant byte first (i.e sparc order)
   735 		     */
   809                      */
   736 #if defined(__MSBFIRST) ||defined(sparc)
   810 #if defined(__MSBFIRST) ||defined(sparc)
   737 		    /*
   811                     /*
   738 		     * mhmh to be measured:
   812                      * mhmh to be measured:
   739 		     *   the if may hurt more than the additional
   813                      *   the if may hurt more than the additional
   740 		     *   memory cycles on some machines ...
   814                      *   memory cycles on some machines ...
   741 		     */
   815                      */
   742 		    if (((INT)byteP & 1) == 0) {
   816                     if (((INT)byteP & 1) == 0) {
   743 			/* aligned */
   817                         /* aligned */
   744 			val = ((unsigned short *)byteP)[0]; 
   818                         val = ((unsigned short *)byteP)[0]; 
   745 		    } else
   819                     } else
   746 #endif
   820 #endif
   747 		    {
   821                     {
   748 			val = byteP[0];
   822                         val = byteP[0];
   749 			val = (val << 8) + byteP[1];
   823                         val = (val << 8) + byteP[1];
   750 		    }
   824                     }
   751 		} else {
   825                 } else {
   752 		    /*
   826                     /*
   753 		     * least significant byte first (i.e i386/alpha order)
   827                      * least significant byte first (i.e i386/alpha order)
   754 		     */
   828                      */
   755 #if defined(i386) || (defined(__LSBFIRST) && defined(UNALIGNED_FETCH_OK))
   829 #if defined(i386) || (defined(__LSBFIRST) && defined(UNALIGNED_FETCH_OK))
   756 		    val = ((unsigned short *)byteP)[0];
   830                     val = ((unsigned short *)byteP)[0];
   757 #else
   831 #else
   758 # if defined(__LSBFIRST)
   832 # if defined(__LSBFIRST)
   759 		    /*
   833                     /*
   760 		     * mhmh to be measured:
   834                      * mhmh to be measured:
   761 		     *   the if may hurt more than the additional
   835                      *   the if may hurt more than the additional
   762 		     *   memory cycles on some machines ...
   836                      *   memory cycles on some machines ...
   763 		     */
   837                      */
   764 		    if (((INT)byteP & 1) == 0) {
   838                     if (((INT)byteP & 1) == 0) {
   765 			/* aligned */
   839                         /* aligned */
   766 			val = ((unsigned short *)byteP)[0];
   840                         val = ((unsigned short *)byteP)[0];
   767 		    } else
   841                     } else
   768 # endif
   842 # endif
   769 		    {
   843                     {
   770 			val = byteP[1];
   844                         val = byteP[1];
   771 			val = (val << 8) + byteP[0];
   845                         val = (val << 8) + byteP[0];
   772 		    }
   846                     }
   773 #endif
   847 #endif
   774 		}
   848                 }
   775 		RETURN ( __MKSMALLINT(val) );
   849                 RETURN ( __MKSMALLINT(val) );
   776 	    }
   850             }
   777 	}
   851         }
   778     }
   852     }
   779 %}.
   853 %}.
   780     ^ SubscriptOutOfBoundsSignal raise.
   854     ^ super wordAt:index MSB:msb
       
   855 
   781 !
   856 !
   782 
   857 
   783 wordAt:index put:value
   858 wordAt:index put:value
   784     "set the 2-bytes starting at index from the (unsigned) Integer value.
   859     "set the 2-bytes starting at index from the (unsigned) Integer value.
   785      The stored value must be in the range 0 .. 16rFFFF. 
   860      The stored value must be in the range 0 .. 16rFFFF. 
   792 
   867 
   793     REGISTER int indx;
   868     REGISTER int indx;
   794     int nIndex;
   869     int nIndex;
   795     int v;
   870     int v;
   796     union {
   871     union {
   797 	unsigned char u_char[2];
   872         unsigned char u_char[2];
   798 	unsigned short u_ushort;
   873         unsigned short u_ushort;
   799     } val;
   874     } val;
   800     OBJ cls;
   875     OBJ cls;
   801     unsigned char *byteP;
   876     unsigned char *byteP;
   802 
   877 
   803     if (__bothSmallInteger(index, value)) {
   878     if (__bothSmallInteger(index, value)) {
   804 	indx = __intVal(index);
   879         indx = __intVal(index);
   805 	if (indx > 0) {
   880         if (indx > 0) {
   806 	    if ((cls = __qClass(self)) != @global(ByteArray))
   881             if ((cls = __qClass(self)) != @global(ByteArray))
   807 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   882                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   808 	    nIndex = __byteArraySize(self);
   883             nIndex = __byteArraySize(self);
   809 	    if ((indx+1) <= nIndex) {
   884             if ((indx+1) <= nIndex) {
   810 		val.u_ushort = v = __intVal(value);
   885                 val.u_ushort = v = __intVal(value);
   811 		if ((v & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   886                 if ((v & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   812 		    byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   887                     byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   813 #if defined(i386) || defined(UNALIGNED_FETCH_OK)
   888 #if defined(i386) || defined(UNALIGNED_FETCH_OK)
   814 		    ((unsigned short *)byteP)[0] = val.u_ushort;
   889                     ((unsigned short *)byteP)[0] = val.u_ushort;
   815 #else
   890 #else
   816 		    /*
   891                     /*
   817 		     * mhmh to be measured:
   892                      * mhmh to be measured:
   818 		     *   the if may hurt more than the additional
   893                      *   the if may hurt more than the additional
   819 		     *   memory cycles on some machines ...
   894                      *   memory cycles on some machines ...
   820 		     */
   895                      */
   821 		    if (((INT)byteP & 1) == 0) {
   896                     if (((INT)byteP & 1) == 0) {
   822 			/* aligned */
   897                         /* aligned */
   823 			((unsigned short *)byteP)[0] = val.u_ushort;
   898                         ((unsigned short *)byteP)[0] = val.u_ushort;
   824 		    } else {
   899                     } else {
   825 			byteP[0] = val.u_char[0];
   900                         byteP[0] = val.u_char[0];
   826 			byteP[1] = val.u_char[1];
   901                         byteP[1] = val.u_char[1];
   827 		    }
   902                     }
   828 #endif
   903 #endif
   829 		    RETURN ( value );
   904                     RETURN ( value );
   830 		}
   905                 }
   831 	    }
   906             }
   832 	}
   907         }
   833     }
   908     }
   834 %}.
   909 %}.
   835     ((value < 0) or:[value > 16rFFFF]) ifTrue:[
   910     ^ super wordAt:index put:value
   836 	^ self elementBoundsError
       
   837     ].
       
   838     ^ SubscriptOutOfBoundsSignal raise.
       
   839 
   911 
   840     "
   912     "
   841      |b|
   913      |b|
   842      b := ByteArray new:4.
   914      b := ByteArray new:4.
   843      b wordAt:1 put:16r0102.
   915      b wordAt:1 put:16r0102.
   860     int val;
   932     int val;
   861     OBJ cls;
   933     OBJ cls;
   862     unsigned char *byteP;
   934     unsigned char *byteP;
   863 
   935 
   864     if (__bothSmallInteger(index, value)) {
   936     if (__bothSmallInteger(index, value)) {
   865 	indx = __intVal(index);
   937         indx = __intVal(index);
   866 	if (indx > 0) {
   938         if (indx > 0) {
   867 	    if ((cls = __qClass(self)) != @global(ByteArray))
   939             if ((cls = __qClass(self)) != @global(ByteArray))
   868 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   940                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
   869 	    nIndex = __byteArraySize(self);
   941             nIndex = __byteArraySize(self);
   870 	    if ((indx+1) <= nIndex) {
   942             if ((indx+1) <= nIndex) {
   871 		val = __intVal(value);
   943                 val = __intVal(value);
   872 		if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   944                 if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   873 		    byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   945                     byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   874 		    if (msb == true) {
   946                     if (msb == true) {
   875 			/*
   947                         /*
   876 			 * most significant byte first (i.e sparc order)
   948                          * most significant byte first (i.e sparc order)
   877 			 */
   949                          */
   878 #if defined(__MSBFIRST) ||defined(sparc)
   950 #if defined(__MSBFIRST) ||defined(sparc)
   879 			/*
   951                         /*
   880 			 * mhmh to be measured:
   952                          * mhmh to be measured:
   881 			 *   the if may hurt more than the additional
   953                          *   the if may hurt more than the additional
   882 			 *   memory cycles on some machines ...
   954                          *   memory cycles on some machines ...
   883 			 */
   955                          */
   884 			if (((INT)byteP & 1) == 0) {
   956                         if (((INT)byteP & 1) == 0) {
   885 			    /* aligned */
   957                             /* aligned */
   886 			    ((unsigned short *)byteP)[0] = val;
   958                             ((unsigned short *)byteP)[0] = val;
   887 			} else 
   959                         } else 
   888 #endif
   960 #endif
   889 			{
   961                         {
   890 			    byteP[1] = val & 0xFF;
   962                             byteP[1] = val & 0xFF;
   891 			    byteP[0] = (val>>8) & 0xFF;
   963                             byteP[0] = (val>>8) & 0xFF;
   892 			}
   964                         }
   893 		    } else {
   965                     } else {
   894 			/*
   966                         /*
   895 			 * least significant byte first (i.e i386/alpha order)
   967                          * least significant byte first (i.e i386/alpha order)
   896 			 */
   968                          */
   897 #if defined(i386) || (defined(__LSBFIRST) && defined(UNALIGNED_FETCH_OK))
   969 #if defined(i386) || (defined(__LSBFIRST) && defined(UNALIGNED_FETCH_OK))
   898 			((unsigned short *)byteP)[0] = val;
   970                         ((unsigned short *)byteP)[0] = val;
   899 #else
   971 #else
   900 # if defined(__LSBFIRST)
   972 # if defined(__LSBFIRST)
   901 			/*
   973                         /*
   902 			 * mhmh to be measured:
   974                          * mhmh to be measured:
   903 			 *   the if may hurt more than the additional
   975                          *   the if may hurt more than the additional
   904 			 *   memory cycles on some machines ...
   976                          *   memory cycles on some machines ...
   905 			 */
   977                          */
   906 			if (((INT)byteP & 1) == 0) {
   978                         if (((INT)byteP & 1) == 0) {
   907 			    /* aligned */
   979                             /* aligned */
   908 			    ((unsigned short *)byteP)[0] = val;
   980                             ((unsigned short *)byteP)[0] = val;
   909 			} else 
   981                         } else 
   910 # endif
   982 # endif
   911 			{
   983                         {
   912 			    byteP[0] = val & 0xFF;
   984                             byteP[0] = val & 0xFF;
   913 			    byteP[1] = (val>>8) & 0xFF;
   985                             byteP[1] = (val>>8) & 0xFF;
   914 			}
   986                         }
   915 #endif
   987 #endif
   916 		    }
   988                     }
   917 		    RETURN ( value );
   989                     RETURN ( value );
   918 		}
   990                 }
   919 	    }
   991             }
   920 	}
   992         }
   921     }
   993     }
   922 %}.
   994 %}.
   923     ((value < 0) or:[value > 16rFFFF]) ifTrue:[
   995     ^ super wordAt:index put:value MSB:msb
   924 	^ self elementBoundsError
       
   925     ].
       
   926     ^ SubscriptOutOfBoundsSignal raise.
       
   927 
   996 
   928     "
   997     "
   929      |b|
   998      |b|
   930      b := ByteArray new:8.
   999      b := ByteArray new:8.
   931      b wordAt:1 put:16r0102 MSB:false.
  1000      b wordAt:1 put:16r0102 MSB:false.
  1665     "perform a special case of an aligned bitBlit operation.
  1734     "perform a special case of an aligned bitBlit operation.
  1666      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result 
  1735      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result 
  1667      of some logical operation, as specified by the ruleSymbol.
  1736      of some logical operation, as specified by the ruleSymbol.
  1668      SourceBytes are fetched starting at sourceOffset.
  1737      SourceBytes are fetched starting at sourceOffset.
  1669      Valid rule symbols are:
  1738      Valid rule symbols are:
  1670 	#copy    - trivial;  same as replaceBytesFrom:to:with:startingAt:
  1739         #copy    - trivial;  same as replaceBytesFrom:to:with:startingAt:
  1671 	#bitXor: - xoring;   byte[dI] = byte[dI] bitXor:(srcByte[sI])
  1740         #bitXor: - xoring;   byte[dI] = byte[dI] bitXor:(srcByte[sI])
  1672 	#bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:(srcByte[sI])
  1741         #bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:(srcByte[sI])
  1673 	#bitOr:  - oring;    byte[dI] = byte[dI] bitOr:(srcByte[sI])
  1742         #bitOr:  - oring;    byte[dI] = byte[dI] bitOr:(srcByte[sI])
  1674 	#+       - adding;   byte[dI] = (byte[dI] + (srcByte[sI])) mod: 256
  1743         #+       - adding;   byte[dI] = (byte[dI] + (srcByte[sI])) mod: 256
  1675 	#-       - subtract; byte[dI] = (byte[dI] - (srcByte[sI])) mod: 256
  1744         #-       - subtract; byte[dI] = (byte[dI] - (srcByte[sI])) mod: 256
  1676      Warning: this is a destructive operation - elements in the receiver are overwritten.
  1745      Warning: this is a destructive operation - elements in the receiver are overwritten.
  1677     "
  1746     "
  1678 
  1747 
  1679     |srcIdx|
  1748     |srcIdx|
  1680 
  1749 
  1682     if ((__isByteArray(sourceBytes)) 
  1751     if ((__isByteArray(sourceBytes)) 
  1683      && (__qClass(self) == ByteArray)
  1752      && (__qClass(self) == ByteArray)
  1684      && __isSmallInteger(dstStart)
  1753      && __isSmallInteger(dstStart)
  1685      && __isSmallInteger(dstEnd)
  1754      && __isSmallInteger(dstEnd)
  1686      && __isSmallInteger(sourceStart)) {
  1755      && __isSmallInteger(sourceStart)) {
  1687 	unsigned char *srcP = __ByteArrayInstPtr(sourceBytes)->ba_element;
  1756         unsigned char *srcP = __ByteArrayInstPtr(sourceBytes)->ba_element;
  1688 	unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
  1757         unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
  1689 	int srcLen = __byteArraySize(sourceBytes);
  1758         int srcLen = __byteArraySize(sourceBytes);
  1690 	int dstLen = __byteArraySize(self);
  1759         int dstLen = __byteArraySize(self);
  1691 	int __srcStart = __intVal(sourceStart);
  1760         int __srcStart = __intVal(sourceStart);
  1692 	int __dstStart = __intVal(dstStart);
  1761         int __dstStart = __intVal(dstStart);
  1693 	int count = __intVal(dstEnd) - __dstStart + 1;
  1762         int count = __intVal(dstEnd) - __dstStart + 1;
  1694 
  1763 
  1695 	if ((__dstStart >= 1)
  1764         if ((__dstStart >= 1)
  1696 	 && (__srcStart >= 1)
  1765          && (__srcStart >= 1)
  1697 	 && ((__dstStart + count - 1) <= dstLen)
  1766          && ((__dstStart + count - 1) <= dstLen)
  1698 	 && ((__srcStart + count - 1) <= srcLen)) {
  1767          && ((__srcStart + count - 1) <= srcLen)) {
  1699 	    srcP += __srcStart - 1;
  1768             srcP += __srcStart - 1;
  1700 	    dstP += __dstStart - 1;
  1769             dstP += __dstStart - 1;
       
  1770 
       
  1771 #define OP_LOOP_BYTES(OP) \
       
  1772     while (count > 0) {                                              \
       
  1773         *dstP OP (*srcP);                                            \
       
  1774         srcP++;                                                      \
       
  1775         dstP++;                                                      \
       
  1776         count--;                                                     \
       
  1777     }                                                                
  1701 
  1778 
  1702 #define OP_LOOP(OP) \
  1779 #define OP_LOOP(OP) \
  1703     while (count > 16) {                                             \
  1780     while (count >= 16) {                                            \
  1704 	((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1781         ((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1705 	((unsigned int *)dstP)[1] OP (((unsigned int *)srcP)[1]);    \
  1782         ((unsigned int *)dstP)[1] OP (((unsigned int *)srcP)[1]);    \
  1706 	((unsigned int *)dstP)[2] OP (((unsigned int *)srcP)[2]);    \
  1783         ((unsigned int *)dstP)[2] OP (((unsigned int *)srcP)[2]);    \
  1707 	((unsigned int *)dstP)[3] OP (((unsigned int *)srcP)[3]);    \
  1784         ((unsigned int *)dstP)[3] OP (((unsigned int *)srcP)[3]);    \
  1708 	srcP += 16;                                                  \
  1785         srcP += 16;                                                  \
  1709 	dstP += 16;                                                  \
  1786         dstP += 16;                                                  \
  1710 	count -= 16;                                                 \
  1787         count -= 16;                                                 \
  1711     }                                                                \
  1788     }                                                                \
  1712     while (count > 4) {                                              \
  1789     while (count >= 4) {                                             \
  1713 	((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1790         ((unsigned int *)dstP)[0] OP (((unsigned int *)srcP)[0]);    \
  1714 	srcP += 4;                                                   \
  1791         srcP += 4;                                                   \
  1715 	dstP += 4;                                                   \
  1792         dstP += 4;                                                   \
  1716 	count -= 4;                                                  \
  1793         count -= 4;                                                  \
  1717     }                                                                \
  1794     }                                                                \
  1718     while (count > 0) {                                              \
  1795     while (count > 0) {                                              \
  1719 	*dstP OP (*srcP);                                            \
  1796         *dstP OP (*srcP);                                            \
  1720 	srcP++;                                                      \
  1797         srcP++;                                                      \
  1721 	dstP++;                                                      \
  1798         dstP++;                                                      \
  1722 	count--;                                                     \
  1799         count--;                                                     \
  1723     }                                                                
  1800     }                                                                
  1724 
  1801 
  1725 
  1802 
  1726 	    if (ruleSymbol == @symbol(bitXor:)) {
  1803             if (ruleSymbol == @symbol(bitXor:)) {
  1727 		OP_LOOP( ^= )
  1804                 OP_LOOP( ^= )
  1728 		RETURN (self);
  1805                 RETURN (self);
  1729 	    }
  1806             }
  1730 	    if (ruleSymbol == @symbol(bitXorNot:)) {
  1807             if (ruleSymbol == @symbol(bitXorNot:)) {
  1731 		OP_LOOP( ^=~ )
  1808                 OP_LOOP( ^=~ )
  1732 		RETURN (self);
  1809                 RETURN (self);
  1733 	    }
  1810             }
  1734 	    if (ruleSymbol == @symbol(bitAnd:)) {
  1811             if (ruleSymbol == @symbol(bitAnd:)) {
  1735 		OP_LOOP( &= )
  1812                 OP_LOOP( &= )
  1736 		RETURN (self);
  1813                 RETURN (self);
  1737 	    }
  1814             }
  1738 	    if (ruleSymbol == @symbol(bitAndNot:)) {
  1815             if (ruleSymbol == @symbol(bitAndNot:)) {
  1739 		OP_LOOP( &=~ )
  1816                 OP_LOOP( &=~ )
  1740 		RETURN (self);
  1817                 RETURN (self);
  1741 	    }
  1818             }
  1742 	    if (ruleSymbol == @symbol(bitOr:)) {
  1819             if (ruleSymbol == @symbol(bitOr:)) {
  1743 		OP_LOOP( |= )
  1820                 OP_LOOP( |= )
  1744 		RETURN (self);
  1821                 RETURN (self);
  1745 	    }
  1822             }
  1746 	    if (ruleSymbol == @symbol(bitOrNot:)) {
  1823             if (ruleSymbol == @symbol(bitOrNot:)) {
  1747 		OP_LOOP( |=~ )
  1824                 OP_LOOP( |=~ )
  1748 		RETURN (self);
  1825                 RETURN (self);
  1749 	    }
  1826             }
  1750 	    if (ruleSymbol == @symbol(copy)) {
  1827             if (ruleSymbol == @symbol(copy)) {
  1751 		OP_LOOP( = )
  1828                 OP_LOOP( = )
  1752 		RETURN (self);
  1829                 RETURN (self);
  1753 	    }
  1830             }
  1754 	    if (ruleSymbol == @symbol(copyNot)) {
  1831             if (ruleSymbol == @symbol(copyNot)) {
  1755 		OP_LOOP( =~ )
  1832                 OP_LOOP( =~ )
  1756 		RETURN (self);
  1833                 RETURN (self);
  1757 	    }
  1834             }
  1758 	    if (ruleSymbol == @symbol(+)) {
  1835             if (ruleSymbol == @symbol(+)) {
  1759 		OP_LOOP( += )
  1836                 OP_LOOP_BYTES( += )
  1760 		RETURN (self);
  1837                 RETURN (self);
  1761 	    }
  1838             }
  1762 	    if (ruleSymbol == @symbol(-)) {
  1839             if (ruleSymbol == @symbol(-)) {
  1763 		OP_LOOP( -= )
  1840                 OP_LOOP_BYTES( -= )
  1764 		RETURN (self);
  1841                 RETURN (self);
  1765 	    }
  1842             }
  1766 	}
  1843         }
  1767     }
  1844     }
  1768 %}.
  1845 %}.
  1769     ruleSymbol == #copy ifTrue:[
  1846     ruleSymbol == #copy ifTrue:[
  1770 	self replaceFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart.
  1847         self replaceFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart.
  1771 	^ self
  1848         ^ self
  1772     ].
  1849     ].
  1773 
  1850 
  1774     srcIdx := sourceStart.
  1851     srcIdx := sourceStart.
  1775     dstStart to:dstEnd do:[:dstIdx |
  1852     dstStart to:dstEnd do:[:dstIdx |
  1776 	self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:(sourceBytes at:srcIdx)).
  1853         self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:(sourceBytes at:srcIdx)).
  1777 	srcIdx := srcIdx + 1.
  1854         srcIdx := srcIdx + 1.
  1778     ].
  1855     ].
  1779 
  1856 
  1780     "
  1857     "
  1781      #[1 2 3 4 5 6 7 8]
  1858      #[1 2 3 4 5 6 7 8]
  1782 	bitBlitBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  1859         bitBlitBytesFrom:1 to:3 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  1783      #[1 2 3 4 5 6 7 8]
  1860      #[1 2 3 4 5 6 7 8]
  1784 	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  1861         bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#bitXor:
  1785      #[1 2 3 4 5 6 7 8]
  1862      #[1 2 3 4 5 6 7 8]
  1786 	bitBlitBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#bitAnd:
  1863         bitBlitBytesFrom:1 to:8 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#bitAnd:
  1787      #[1 2 3 4 5 6 7 8]
  1864      #[1 2 3 4 5 6 7 8]
  1788 	bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+
  1865         bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+  
       
  1866      #[255 0 0 0 0 0 0 0]
       
  1867         bitBlitBytesFrom:1 to:8 with:#[1 2 3 4 5 6 7 8] startingAt:1 rule:#+   
  1789      #[1 2 3 4 5 6 7 8]
  1868      #[1 2 3 4 5 6 7 8]
  1790 	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#+
  1869         bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 1 1 1 1] startingAt:1 rule:#+
  1791      #[1 2 3 4 5 6 7 8]
  1870      #[1 2 3 4 5 6 7 8]
  1792 	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#+
  1871         bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#+
  1793      #[1 2 3 4 5 6 7 8]
  1872      #[1 2 3 4 5 6 7 8]
  1794 	bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#copyNot
  1873         bitBlitBytesFrom:1 to:4 with:#[1 1 1 1 2 2 2 2] startingAt:5 rule:#copyNot
  1795 
  1874 
  1796      #[1 2 3 4 5 6 7 8]
  1875      #[1 2 3 4 5 6 7 8]
  1797 	bitBlitBytesFrom:1 to:8 with:(1 to:8) startingAt:1 rule:#+
  1876         bitBlitBytesFrom:1 to:8 with:(1 to:8) startingAt:1 rule:#+
       
  1877     "
       
  1878 !
       
  1879 
       
  1880 bitBlitBytesFrom:dstStart to:dstEnd withConstant:sourceByte rule:ruleSymbol
       
  1881     "perform a special case of an aligned bitBlit operation.
       
  1882      Bytes in the receiver from dstStart to dstEnd are destructively replaced by the result 
       
  1883      of some logical operation, as specified by the ruleSymbol.
       
  1884      Valid rule symbols are:
       
  1885         #copy    - trivial;  same as from:to:put:
       
  1886         #bitXor: - xoring;   byte[dI] = byte[dI] bitXor:sourceConst
       
  1887         #bitAnd: - anding;   byte[dI] = byte[dI] bitAnd:sourceConst
       
  1888         #bitOr:  - oring;    byte[dI] = byte[dI] bitOr:sourceConst
       
  1889         #+       - adding;   byte[dI] = (byte[dI] + sourceConst) mod: 256
       
  1890         #-       - subtract; byte[dI] = (byte[dI] - sourceConst) mod: 256
       
  1891      Warning: this is a destructive operation - elements in the receiver are overwritten.
       
  1892     "
       
  1893 
       
  1894     |srcIdx|
       
  1895 
       
  1896 %{
       
  1897     if ((__qClass(self) == ByteArray)
       
  1898      && __isSmallInteger(dstStart)
       
  1899      && __isSmallInteger(dstEnd)
       
  1900      && __isSmallInteger(sourceByte)) {
       
  1901         unsigned char srcByte = __intVal(sourceByte);
       
  1902         unsigned srcWord;
       
  1903         unsigned char *dstP = __ByteArrayInstPtr(self)->ba_element;
       
  1904         int dstLen = __byteArraySize(self);
       
  1905         int __dstStart = __intVal(dstStart);
       
  1906         int count = __intVal(dstEnd) - __dstStart + 1;
       
  1907 
       
  1908         srcWord = (srcByte << 8) | srcByte;
       
  1909         srcWord = (srcWord << 16) | srcWord;
       
  1910 
       
  1911         if ((__dstStart >= 1)
       
  1912          && ((__dstStart + count - 1) <= dstLen)) {
       
  1913             dstP += __dstStart - 1;
       
  1914 
       
  1915 #define OP_LOOP_BYTES(OP) \
       
  1916     while (count > 0) {                          \
       
  1917         *dstP OP srcByte;                        \
       
  1918         dstP++;                                  \
       
  1919         count--;                                 \
       
  1920     }                                                                
       
  1921 
       
  1922 #define OP_LOOP(OP) \
       
  1923     while (count >= 16) {                        \
       
  1924         ((unsigned int *)dstP)[0] OP srcWord;    \
       
  1925         ((unsigned int *)dstP)[1] OP srcWord;    \
       
  1926         ((unsigned int *)dstP)[2] OP srcWord;    \
       
  1927         ((unsigned int *)dstP)[3] OP srcWord;    \
       
  1928         dstP += 16;                              \
       
  1929         count -= 16;                             \
       
  1930     }                                            \
       
  1931     while (count >= 4) {                         \
       
  1932         ((unsigned int *)dstP)[0] OP srcWord;    \
       
  1933         dstP += 4;                               \
       
  1934         count -= 4;                              \
       
  1935     }                                            \
       
  1936     while (count > 0) {                          \
       
  1937         *dstP OP srcByte;                        \
       
  1938         dstP++;                                  \
       
  1939         count--;                                 \
       
  1940     }                                                                
       
  1941 
       
  1942 
       
  1943             if (ruleSymbol == @symbol(bitXor:)) {
       
  1944                 OP_LOOP( ^= )
       
  1945                 RETURN (self);
       
  1946             }
       
  1947             if (ruleSymbol == @symbol(bitXorNot:)) {
       
  1948                 OP_LOOP( ^=~ )
       
  1949                 RETURN (self);
       
  1950             }
       
  1951             if (ruleSymbol == @symbol(bitAnd:)) {
       
  1952                 OP_LOOP( &= )
       
  1953                 RETURN (self);
       
  1954             }
       
  1955             if (ruleSymbol == @symbol(bitAndNot:)) {
       
  1956                 OP_LOOP( &=~ )
       
  1957                 RETURN (self);
       
  1958             }
       
  1959             if (ruleSymbol == @symbol(bitOr:)) {
       
  1960                 OP_LOOP( |= )
       
  1961                 RETURN (self);
       
  1962             }
       
  1963             if (ruleSymbol == @symbol(bitOrNot:)) {
       
  1964                 OP_LOOP( |=~ )
       
  1965                 RETURN (self);
       
  1966             }
       
  1967             if (ruleSymbol == @symbol(copy)) {
       
  1968                 OP_LOOP( = )
       
  1969                 RETURN (self);
       
  1970             }
       
  1971             if (ruleSymbol == @symbol(copyNot)) {
       
  1972                 OP_LOOP( =~ )
       
  1973                 RETURN (self);
       
  1974             }
       
  1975             if (ruleSymbol == @symbol(+)) {
       
  1976                 OP_LOOP_BYTES( += )
       
  1977                 RETURN (self);
       
  1978             }
       
  1979             if (ruleSymbol == @symbol(-)) {
       
  1980                 OP_LOOP_BYTES( -= )
       
  1981                 RETURN (self);
       
  1982             }
       
  1983         }
       
  1984     }
       
  1985 %}.
       
  1986     ruleSymbol == #copy ifTrue:[
       
  1987         self from:dstStart to:dstEnd put:sourceByte.
       
  1988         ^ self
       
  1989     ].
       
  1990 
       
  1991     dstStart to:dstEnd do:[:dstIdx |
       
  1992         self at:dstIdx put:((self at:dstIdx) perform:ruleSymbol with:sourceByte).
       
  1993     ].
       
  1994 
       
  1995     "
       
  1996      #[1 2 3 4 5 6 7 8]
       
  1997         bitBlitBytesFrom:1 to:3 withConstant:1 rule:#bitXor:     
       
  1998      #[1 2 3 4 5 6 7 8]
       
  1999         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitXor:
       
  2000      #[1 2 3 4 5 6 7 8]
       
  2001         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#bitAnd:    
       
  2002      #[1 2 3 4 5 6 7 8]
       
  2003         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+  
       
  2004      #[255 0 0 0 0 0 0 0]
       
  2005         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+     
       
  2006      #[1 2 3 4 5 6 7 8]
       
  2007         bitBlitBytesFrom:1 to:4 withConstant:1 rule:#+   
       
  2008      #[1 2 3 4 5 6 7 8]
       
  2009         bitBlitBytesFrom:1 to:4 withConstant:1 rule:#-       
       
  2010      #[1 2 3 4 5 6 7 8]
       
  2011         bitBlitBytesFrom:1 to:4 withConstant:1 rule:#copyNot
       
  2012 
       
  2013      #[1 2 3 4 5 6 7 8]
       
  2014         bitBlitBytesFrom:1 to:8 withConstant:1 rule:#+
  1798     "
  2015     "
  1799 !
  2016 !
  1800 
  2017 
  1801 bitOrBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart 
  2018 bitOrBytesFrom:dstStart to:dstEnd with:sourceBytes startingAt:sourceStart 
  1802     "replace bytes in the receiver with the result of a bitOr operation.
  2019     "replace bytes in the receiver with the result of a bitOr operation.
  2188     REGISTER unsigned char *dst;
  2405     REGISTER unsigned char *dst;
  2189     REGISTER unsigned long *ldst;
  2406     REGISTER unsigned long *ldst;
  2190     REGISTER int cnt;
  2407     REGISTER int cnt;
  2191 
  2408 
  2192     if (__qClass(self) == @global(ByteArray)) {
  2409     if (__qClass(self) == @global(ByteArray)) {
  2193 	cnt = __byteArraySize(self);
  2410         cnt = __byteArraySize(self);
  2194 	dst = __ByteArrayInstPtr(self)->ba_element;
  2411         dst = __ByteArrayInstPtr(self)->ba_element;
  2195 	if (! ((INT)dst & (sizeof(long)-1))) {
  2412         if (! ((INT)dst & (sizeof(long)-1))) {
  2196 	    ldst = (unsigned long *)dst;
  2413             ldst = (unsigned long *)dst;
  2197 	    while (cnt >= (sizeof(long))*4) {
  2414             while (cnt >= (sizeof(long))*4) {
  2198 		ldst[0] = ~(ldst[0]);
  2415                 ldst[0] = ~(ldst[0]);
  2199 		ldst[1] = ~(ldst[1]);
  2416                 ldst[1] = ~(ldst[1]);
  2200 		ldst[2] = ~(ldst[2]);
  2417                 ldst[2] = ~(ldst[2]);
  2201 		ldst[3] = ~(ldst[3]);
  2418                 ldst[3] = ~(ldst[3]);
  2202 		ldst += 4;
  2419                 ldst += 4;
  2203 		cnt -= (sizeof(long))*4;
  2420                 cnt -= (sizeof(long))*4;
  2204 	    }
  2421             }
  2205 	    while (cnt >= sizeof(long)) {
  2422             while (cnt >= sizeof(long)) {
  2206 		*ldst = ~(*ldst);
  2423                 *ldst = ~(*ldst);
  2207 		ldst++;
  2424                 ldst++;
  2208 		cnt -= sizeof(long);
  2425                 cnt -= sizeof(long);
  2209 	    }
  2426             }
  2210 	    dst = (unsigned char *)ldst;
  2427             dst = (unsigned char *)ldst;
  2211 	}
  2428         }
  2212 	while (cnt--) {
  2429         while (cnt--) {
  2213 	    *dst = ~(*dst);
  2430             *dst = ~(*dst);
  2214 	    dst++;
  2431             dst++;
  2215 	}
  2432         }
  2216 	RETURN ( self );
  2433         RETURN ( self );
  2217     }
  2434     }
  2218 %}.
  2435 %}.
  2219     self primitiveFailed
  2436     self bitBlitBytesFrom:1 to:self size withConstant:16rFF rule:#bitXor:
  2220 
  2437 
  2221     "
  2438     "
  2222      #[1 2 3 4 5 6 7 8 9 10] copy invert
  2439      #[1 2 3 4 5 6 7 8 9 10] copy invert
       
  2440      #[1 2 3 4 5 6 7 8 9 10] copy 
       
  2441         bitBlitBytesFrom:1 to:10 withConstant:16rFF rule:#bitXor: 
  2223     "
  2442     "
  2224 !
  2443 !
  2225 
  2444 
  2226 reverse
  2445 reverse
  2227     "reverse the order of my elements inplace - 
  2446     "reverse the order of my elements inplace - 
  2437             p[__i2] = t;
  2656             p[__i2] = t;
  2438         }
  2657         }
  2439         RETURN ( self );
  2658         RETURN ( self );
  2440     }
  2659     }
  2441 %}.
  2660 %}.
  2442     ^ super swapIndex:i1 and:i2
  2661     ^ super swapIndex:i1 and:i2 "/ rubbish - there is no one currenl
  2443 
  2662 
  2444     "
  2663     "
  2445      #[1 2 3 4 5 6 7 8 9 10] copy swapIndex:1 and:10 
  2664      #[1 2 3 4 5 6 7 8 9 10] copy swapIndex:1 and:10 
  2446      #[1 2 3 4 5 6 7 8 9 10 11] copy swapIndex:5 and:6  
  2665      #[1 2 3 4 5 6 7 8 9 10 11] copy swapIndex:5 and:6  
  2447     "
  2666     "
  2936 ! !
  3155 ! !
  2937 
  3156 
  2938 !ByteArray class methodsFor:'documentation'!
  3157 !ByteArray class methodsFor:'documentation'!
  2939 
  3158 
  2940 version
  3159 version
  2941     ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.138 2000-06-26 14:35:15 cg Exp $'
  3160     ^ '$Header: /cvs/stx/stx/libbasic/ByteArray.st,v 1.139 2000-07-02 12:52:07 cg Exp $'
  2942 ! !
  3161 ! !