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 " |
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 " |