ByteArray.st
changeset 19048 0929f428048d
parent 18966 3bc73a4cdae6
child 19054 80cbbad08d0c
child 19134 eaa91cb0ef1b
equal deleted inserted replaced
19047:035b338ef201 19048:0929f428048d
   162 %}.
   162 %}.
   163     ^ self basicNew:anInteger
   163     ^ self basicNew:anInteger
   164 ! !
   164 ! !
   165 
   165 
   166 
   166 
   167 
       
   168 !ByteArray class methodsFor:'queries'!
   167 !ByteArray class methodsFor:'queries'!
   169 
   168 
   170 elementByteSize
   169 elementByteSize
   171     "for bit-like containers, return the number of bytes stored per element.
   170     "for bit-like containers, return the number of bytes stored per element.
   172      Here, 1 is returned"
   171      Here, 1 is returned"
   182 
   181 
   183     ^ self == ByteArray
   182     ^ self == ByteArray
   184 
   183 
   185     "Modified: 23.4.1996 / 15:56:25 / cg"
   184     "Modified: 23.4.1996 / 15:56:25 / cg"
   186 ! !
   185 ! !
   187 
       
   188 
   186 
   189 !ByteArray methodsFor:'Compatibility-Squeak'!
   187 !ByteArray methodsFor:'Compatibility-Squeak'!
   190 
   188 
   191 bitXor:aByteArray
   189 bitXor:aByteArray
   192     "return a new byteArray containing the bitWise-xor of the receiver's and the
   190     "return a new byteArray containing the bitWise-xor of the receiver's and the
   671 !ByteArray methodsFor:'accessing-shorts'!
   669 !ByteArray methodsFor:'accessing-shorts'!
   672 
   670 
   673 wordAt:index
   671 wordAt:index
   674     "return the 2-bytes starting at index as an (unsigned) Integer.
   672     "return the 2-bytes starting at index as an (unsigned) Integer.
   675      The value is retrieved in the machines natural byte order
   673      The value is retrieved in the machines natural byte order
       
   674      Notice: 
       
   675         the index is a byte index; thus, this allows for unaligned access to
       
   676         words on any boundary.
   676      Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)"
   677      Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)"
   677 
   678 
   678 %{  /* NOCONTEXT */
   679 %{  /* NOCONTEXT */
   679 
   680 
   680     REGISTER int indx;
   681     REGISTER int indx;
   681     int nIndex;
   682     int nIndex;
   682     union {
   683     union {
   683 	unsigned char u_char[2];
   684         unsigned char u_char[2];
   684 	unsigned short u_ushort;
   685         unsigned short u_ushort;
   685     } val;
   686     } val;
   686     unsigned char *byteP;
   687     unsigned char *byteP;
   687 
   688 
   688     if (__isSmallInteger(index)) {
   689     if (__isSmallInteger(index)) {
   689 	indx = __intVal(index);
   690         indx = __intVal(index);
   690 	if (indx > 0) {
   691         if (indx > 0) {
   691 	    if (!__isByteArrayLike(self))
   692             if (!__isByteArrayLike(self))
   692 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   693                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   693 	    nIndex = __byteArraySize(self);
   694             nIndex = __byteArraySize(self);
   694 	    if ((indx+1) <= nIndex) {
   695             if ((indx+1) <= nIndex) {
   695 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   696                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   696 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   697 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   697 		val.u_ushort = ((unsigned short *)byteP)[0];
   698                 val.u_ushort = ((unsigned short *)byteP)[0];
   698 #else
   699 #else
   699 		/*
   700                 /*
   700 		 * mhmh to be measured:
   701                  * mhmh to be measured:
   701 		 *   the if may hurt more than the additional
   702                  *   the if may hurt more than the additional
   702 		 *   memory cycles on some machines ...
   703                  *   memory cycles on some machines ...
   703 		 */
   704                  */
   704 		if (((INT)byteP & 1) == 0) {
   705                 if (((INT)byteP & 1) == 0) {
   705 		    /* aligned */
   706                     /* aligned */
   706 		    val.u_ushort = ((unsigned short *)byteP)[0];
   707                     val.u_ushort = ((unsigned short *)byteP)[0];
   707 		} else {
   708                 } else {
   708 		    val.u_char[0] = byteP[0];
   709                     val.u_char[0] = byteP[0];
   709 		    val.u_char[1] = byteP[1];
   710                     val.u_char[1] = byteP[1];
   710 		}
   711                 }
   711 #endif
   712 #endif
   712 		RETURN ( __mkSmallInteger((val.u_ushort)) );
   713                 RETURN ( __mkSmallInteger((val.u_ushort)) );
   713 	    }
   714             }
   714 	}
   715         }
   715     }
   716     }
   716 %}.
   717 %}.
   717     ^ super wordAt:index
   718     ^ super wordAt:index
   718 !
   719 !
   719 
   720 
   720 wordAt:index MSB:msb
   721 wordAt:index MSB:msb
   721     "return the 2-bytes starting at index as an (unsigned) Integer.
   722     "return the 2-bytes starting at index as an (unsigned) Integer.
   722      The value is retrieved MSB (high 8 bits at lower index) if msb is true;
   723      The value is retrieved MSB (high 8 bits at lower index) if msb is true;
   723      LSB-first (i.e. low 8-bits at lower byte index) if its false.
   724      LSB-first (i.e. low 8-bits at lower byte index) if its false.
       
   725      Notice: 
       
   726         the index is a byte index; thus, this allows for unaligned access to
       
   727         words on any boundary.
   724      Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)"
   728      Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)"
   725 
   729 
   726 %{  /* NOCONTEXT */
   730 %{  /* NOCONTEXT */
   727 
   731 
   728     REGISTER int indx;
   732     REGISTER int indx;
   729     int nIndex;
   733     int nIndex;
   730     int val;
   734     int val;
   731     unsigned char *byteP;
   735     unsigned char *byteP;
   732 
   736 
   733     if (__isSmallInteger(index)) {
   737     if (__isSmallInteger(index)) {
   734 	indx = __intVal(index);
   738         indx = __intVal(index);
   735 	if (indx > 0) {
   739         if (indx > 0) {
   736 	    if (!__isByteArrayLike(self))
   740             if (!__isByteArrayLike(self))
   737 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   741                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   738 	    nIndex = __byteArraySize(self);
   742             nIndex = __byteArraySize(self);
   739 	    if ((indx+1) <= nIndex) {
   743             if ((indx+1) <= nIndex) {
   740 		byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   744                 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   741 		if (msb == true) {
   745                 if (msb == true) {
   742 		    /*
   746                     /*
   743 		     * most significant byte first (i.e sparc order)
   747                      * most significant byte first (i.e sparc order)
   744 		     */
   748                      */
   745 #if defined(__MSBFIRST__)
   749 #if defined(__MSBFIRST__)
   746 		    /*
   750                     /*
   747 		     * mhmh to be measured:
   751                      * mhmh to be measured:
   748 		     *   the if may hurt more than the additional
   752                      *   the if may hurt more than the additional
   749 		     *   memory cycles on some machines ...
   753                      *   memory cycles on some machines ...
   750 		     */
   754                      */
   751 		    if (((INT)byteP & 1) == 0) {
   755                     if (((INT)byteP & 1) == 0) {
   752 			/* aligned */
   756                         /* aligned */
   753 			val = ((unsigned short *)byteP)[0];
   757                         val = ((unsigned short *)byteP)[0];
   754 		    } else
   758                     } else
   755 #endif
   759 #endif
   756 		    {
   760                     {
   757 			val = byteP[0];
   761                         val = byteP[0];
   758 			val = (val << 8) + byteP[1];
   762                         val = (val << 8) + byteP[1];
   759 		    }
   763                     }
   760 		} else {
   764                 } else {
   761 		    /*
   765                     /*
   762 		     * least significant byte first (i.e i386/alpha order)
   766                      * least significant byte first (i.e i386/alpha order)
   763 		     */
   767                      */
   764 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   768 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   765 		    val = ((unsigned short *)byteP)[0];
   769                     val = ((unsigned short *)byteP)[0];
   766 #else
   770 #else
   767 # if defined(__LSBFIRST__)
   771 # if defined(__LSBFIRST__)
   768 		    /*
   772                     /*
   769 		     * mhmh to be measured:
   773                      * mhmh to be measured:
   770 		     *   the if may hurt more than the additional
   774                      *   the if may hurt more than the additional
   771 		     *   memory cycles on some machines ...
   775                      *   memory cycles on some machines ...
   772 		     */
   776                      */
   773 		    if (((INT)byteP & 1) == 0) {
   777                     if (((INT)byteP & 1) == 0) {
   774 			/* aligned */
   778                         /* aligned */
   775 			val = ((unsigned short *)byteP)[0];
   779                         val = ((unsigned short *)byteP)[0];
   776 		    } else
   780                     } else
   777 # endif
   781 # endif
   778 		    {
   782                     {
   779 			val = byteP[1];
   783                         val = byteP[1];
   780 			val = (val << 8) + byteP[0];
   784                         val = (val << 8) + byteP[0];
   781 		    }
   785                     }
   782 #endif
   786 #endif
   783 		}
   787                 }
   784 		RETURN ( __mkSmallInteger(val) );
   788                 RETURN ( __mkSmallInteger(val) );
   785 	    }
   789             }
   786 	}
   790         }
   787     }
   791     }
   788 %}.
   792 %}.
   789     ^ super wordAt:index MSB:msb
   793     ^ super wordAt:index MSB:msb
   790 !
   794 !
   791 
   795 
   793     "set the 2-bytes starting at index from the (unsigned) Integer value.
   797     "set the 2-bytes starting at index from the (unsigned) Integer value.
   794      The stored value must be in the range 0 .. 16rFFFF.
   798      The stored value must be in the range 0 .. 16rFFFF.
   795      The value is stored in the machines natural byteorder,
   799      The value is stored in the machines natural byteorder,
   796      i.e. this method should only be used to fill byteArrays which are
   800      i.e. this method should only be used to fill byteArrays which are
   797      used internally (not passed to other machines).
   801      used internally (not passed to other machines).
       
   802      Notice: 
       
   803         the index is a byte index; thus, this allows for unaligned access to
       
   804         words on any boundary.
   798      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   805      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   799 
   806 
   800 %{  /* NOCONTEXT */
   807 %{  /* NOCONTEXT */
   801 
   808 
   802     REGISTER int indx;
   809     REGISTER int indx;
   803     int nIndex;
   810     int nIndex;
   804     int v;
   811     int v;
   805     union {
   812     union {
   806 	unsigned char u_char[2];
   813         unsigned char u_char[2];
   807 	unsigned short u_ushort;
   814         unsigned short u_ushort;
   808     } val;
   815     } val;
   809     unsigned char *byteP;
   816     unsigned char *byteP;
   810 
   817 
   811     if (__bothSmallInteger(index, value)) {
   818     if (__bothSmallInteger(index, value)) {
   812 	indx = __intVal(index);
   819         indx = __intVal(index);
   813 	if (indx > 0) {
   820         if (indx > 0) {
   814 	    if (!__isByteArrayLike(self))
   821             if (!__isByteArrayLike(self))
   815 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   822                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   816 	    nIndex = __byteArraySize(self);
   823             nIndex = __byteArraySize(self);
   817 	    if ((indx+1) <= nIndex) {
   824             if ((indx+1) <= nIndex) {
   818 		val.u_ushort = v = __intVal(value);
   825                 val.u_ushort = v = __intVal(value);
   819 		if ((v & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   826                 if ((v & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   820 		    byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   827                     byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   821 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   828 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK)
   822 		    ((unsigned short *)byteP)[0] = val.u_ushort;
   829                     ((unsigned short *)byteP)[0] = val.u_ushort;
   823 #else
   830 #else
   824 		    /*
   831                     /*
   825 		     * mhmh to be measured:
   832                      * mhmh to be measured:
   826 		     *   the if may hurt more than the additional
   833                      *   the if may hurt more than the additional
   827 		     *   memory cycles on some machines ...
   834                      *   memory cycles on some machines ...
   828 		     */
   835                      */
   829 		    if (((INT)byteP & 1) == 0) {
   836                     if (((INT)byteP & 1) == 0) {
   830 			/* aligned */
   837                         /* aligned */
   831 			((unsigned short *)byteP)[0] = val.u_ushort;
   838                         ((unsigned short *)byteP)[0] = val.u_ushort;
   832 		    } else {
   839                     } else {
   833 			byteP[0] = val.u_char[0];
   840                         byteP[0] = val.u_char[0];
   834 			byteP[1] = val.u_char[1];
   841                         byteP[1] = val.u_char[1];
   835 		    }
   842                     }
   836 #endif
   843 #endif
   837 		    RETURN ( value );
   844                     RETURN ( value );
   838 		}
   845                 }
   839 	    }
   846             }
   840 	}
   847         }
   841     }
   848     }
   842 %}.
   849 %}.
   843     ^ super wordAt:index put:value
   850     ^ super wordAt:index put:value
   844 
   851 
   845     "
   852     "
   854 wordAt:index put:value MSB:msb
   861 wordAt:index put:value MSB:msb
   855     "set the 2-bytes starting at index from the (unsigned) Integer value.
   862     "set the 2-bytes starting at index from the (unsigned) Integer value.
   856      The stored value must be in the range 0 .. 16rFFFF.
   863      The stored value must be in the range 0 .. 16rFFFF.
   857      The value is stored LSB-first (i.e. the low 8bits are stored at the
   864      The value is stored LSB-first (i.e. the low 8bits are stored at the
   858      lower index) if msb is false, MSB-first otherwise.
   865      lower index) if msb is false, MSB-first otherwise.
       
   866      Notice: 
       
   867         the index is a byte index; thus, this allows for unaligned access to
       
   868         words on any boundary.
   859      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   869      Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)"
   860 
   870 
   861 %{  /* NOCONTEXT */
   871 %{  /* NOCONTEXT */
   862 
   872 
   863     REGISTER int indx;
   873     REGISTER int indx;
   865     int val;
   875     int val;
   866     OBJ cls;
   876     OBJ cls;
   867     unsigned char *byteP;
   877     unsigned char *byteP;
   868 
   878 
   869     if (__bothSmallInteger(index, value)) {
   879     if (__bothSmallInteger(index, value)) {
   870 	indx = __intVal(index);
   880         indx = __intVal(index);
   871 	if (indx > 0) {
   881         if (indx > 0) {
   872 	    if (!__isByteArrayLike(self))
   882             if (!__isByteArrayLike(self))
   873 		indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   883                 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(__qClass(self))->c_ninstvars));
   874 	    nIndex = __byteArraySize(self);
   884             nIndex = __byteArraySize(self);
   875 	    if ((indx+1) <= nIndex) {
   885             if ((indx+1) <= nIndex) {
   876 		val = __intVal(value);
   886                 val = __intVal(value);
   877 		if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   887                 if ((val & ~0xFFFF) == 0 /* i.e. (val >= 0) && (val <= 0xFFFF) */) {
   878 		    byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   888                     byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1;
   879 		    if (msb == true) {
   889                     if (msb == true) {
   880 			/*
   890                         /*
   881 			 * most significant byte first (i.e sparc order)
   891                          * most significant byte first (i.e sparc order)
   882 			 */
   892                          */
   883 #if defined(__MSBFIRST__)
   893 #if defined(__MSBFIRST__)
   884 			/*
   894                         /*
   885 			 * mhmh to be measured:
   895                          * mhmh to be measured:
   886 			 *   the if may hurt more than the additional
   896                          *   the if may hurt more than the additional
   887 			 *   memory cycles on some machines ...
   897                          *   memory cycles on some machines ...
   888 			 */
   898                          */
   889 			if (((INT)byteP & 1) == 0) {
   899                         if (((INT)byteP & 1) == 0) {
   890 			    /* aligned */
   900                             /* aligned */
   891 			    ((unsigned short *)byteP)[0] = val;
   901                             ((unsigned short *)byteP)[0] = val;
   892 			} else
   902                         } else
   893 #endif
   903 #endif
   894 			{
   904                         {
   895 			    byteP[1] = val & 0xFF;
   905                             byteP[1] = val & 0xFF;
   896 			    byteP[0] = (val>>8) & 0xFF;
   906                             byteP[0] = (val>>8) & 0xFF;
   897 			}
   907                         }
   898 		    } else {
   908                     } else {
   899 			/*
   909                         /*
   900 			 * least significant byte first (i.e i386/alpha order)
   910                          * least significant byte first (i.e i386/alpha order)
   901 			 */
   911                          */
   902 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   912 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK))
   903 			((unsigned short *)byteP)[0] = val;
   913                         ((unsigned short *)byteP)[0] = val;
   904 #else
   914 #else
   905 # if defined(__LSBFIRST__)
   915 # if defined(__LSBFIRST__)
   906 			/*
   916                         /*
   907 			 * mhmh to be measured:
   917                          * mhmh to be measured:
   908 			 *   the if may hurt more than the additional
   918                          *   the if may hurt more than the additional
   909 			 *   memory cycles on some machines ...
   919                          *   memory cycles on some machines ...
   910 			 */
   920                          */
   911 			if (((INT)byteP & 1) == 0) {
   921                         if (((INT)byteP & 1) == 0) {
   912 			    /* aligned */
   922                             /* aligned */
   913 			    ((unsigned short *)byteP)[0] = val;
   923                             ((unsigned short *)byteP)[0] = val;
   914 			} else
   924                         } else
   915 # endif
   925 # endif
   916 			{
   926                         {
   917 			    byteP[0] = val & 0xFF;
   927                             byteP[0] = val & 0xFF;
   918 			    byteP[1] = (val>>8) & 0xFF;
   928                             byteP[1] = (val>>8) & 0xFF;
   919 			}
   929                         }
   920 #endif
   930 #endif
   921 		    }
   931                     }
   922 		    RETURN ( value );
   932                     RETURN ( value );
   923 		}
   933                 }
   924 	    }
   934             }
   925 	}
   935         }
   926     }
   936     }
   927 %}.
   937 %}.
   928     ^ super wordAt:index put:value MSB:msb
   938     ^ super wordAt:index put:value MSB:msb
   929 
   939 
   930     "
   940     "
  2921     "
  2931     "
  2922      #[1 2 3 1 2 3 1 2 3 1 2 3 4 5 6 4 5 6] usedValues
  2932      #[1 2 3 1 2 3 1 2 3 1 2 3 4 5 6 4 5 6] usedValues
  2923     "
  2933     "
  2924 ! !
  2934 ! !
  2925 
  2935 
  2926 
       
  2927 !ByteArray methodsFor:'searching'!
  2936 !ByteArray methodsFor:'searching'!
  2928 
  2937 
  2929 indexOf:aByte startingAt:start
  2938 indexOf:aByte startingAt:start
  2930     "return the index of the first occurrence of the argument, aByte
  2939     "return the index of the first occurrence of the argument, aByte
  2931      in the receiver starting at start, anInteger; return 0 if not found.
  2940      in the receiver starting at start, anInteger; return 0 if not found.
  2987     "
  2996     "
  2988      #[1 2 3 4 5 6 7 8 9 0 1 2 3 4 5] indexOf:0 startingAt:1
  2997      #[1 2 3 4 5 6 7 8 9 0 1 2 3 4 5] indexOf:0 startingAt:1
  2989     "
  2998     "
  2990 ! !
  2999 ! !
  2991 
  3000 
  2992 
       
  2993 !ByteArray methodsFor:'testing'!
  3001 !ByteArray methodsFor:'testing'!
  2994 
  3002 
  2995 isByteArray
  3003 isByteArray
  2996     "return true, if the receiver is some kind of bytearray;
  3004     "return true, if the receiver is some kind of bytearray;
  2997      true is returned here - the method is redefined from Object."
  3005      true is returned here - the method is redefined from Object."