511 ^ super basicAt:index put:value |
513 ^ super basicAt:index put:value |
512 ! ! |
514 ! ! |
513 |
515 |
514 !ByteArray methodsFor:'accessing-longs'! |
516 !ByteArray methodsFor:'accessing-longs'! |
515 |
517 |
516 doubleWordAt:index put:value |
518 unsignedInt32At:index put:value |
517 "set the 4-bytes starting at index from the (unsigned) Integer value. |
519 "set the 4-bytes starting at index from the (unsigned) Integer value. |
518 The value should be in the range 0 to 16rFFFFFFFF |
520 The value should be in the range 0 to 16rFFFFFFFF |
519 (for negative values, the stored value is not defined). |
521 (for negative values, the stored value is not defined). |
520 The value is stored in the machines natural byte order. |
522 The value is stored in the machine's natural byte order. |
521 Q: should it store signed values ? (see ByteArray signedDoubleWordAt:put:)" |
523 Q: should it store signed values ? (see ByteArray signedDoubleWordAt:put:)" |
522 |
524 |
523 |t| |
525 |t| |
524 |
526 |
525 %{ /* NOCONTEXT */ |
527 %{ /* NOCONTEXT */ |
526 |
528 |
527 REGISTER int indx; |
529 REGISTER int indx; |
528 int nIndex; |
530 int nIndex; |
529 union { |
531 union { |
530 unsigned char u_char[4]; |
532 unsigned char u_char[4]; |
531 unsigned int u_uint; |
533 unsigned int u_uint; |
532 } val; |
534 } val; |
533 OBJ cls; |
535 OBJ cls; |
534 unsigned char *byteP; |
536 unsigned char *byteP; |
535 |
537 |
536 if (__isSmallInteger(index)) { |
538 if (__isSmallInteger(index)) { |
537 if (__isSmallInteger(value)) { |
539 if (__isSmallInteger(value)) { |
538 val.u_uint = __intVal(value); |
540 val.u_uint = __intVal(value); |
539 } else { |
541 } else { |
540 val.u_uint = __longIntVal(value); |
542 val.u_uint = __longIntVal(value); |
541 if (val.u_uint == 0) goto error; |
543 if (val.u_uint == 0) goto error; |
542 } |
544 } |
543 |
545 |
544 indx = __intVal(index); |
546 indx = __intVal(index); |
545 if (indx > 0) { |
547 if (indx > 0) { |
546 if ((cls = __qClass(self)) != @global(ByteArray)) |
548 if ((cls = __qClass(self)) != @global(ByteArray)) |
547 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); |
549 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); |
548 nIndex = __qSize(self) - OHDR_SIZE; |
550 nIndex = __qSize(self) - OHDR_SIZE; |
549 if ((indx+3) <= nIndex) { |
551 if ((indx+3) <= nIndex) { |
550 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1; |
552 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1; |
551 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK) |
553 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK) |
552 ((unsigned int *)byteP)[0] = val.u_uint; |
554 ((unsigned int *)byteP)[0] = val.u_uint; |
553 #else |
555 #else |
554 if (((unsigned INT)byteP & 3) == 0) { |
556 if (((unsigned INT)byteP & 3) == 0) { |
555 ((unsigned int *)byteP)[0] = val.u_uint; |
557 ((unsigned int *)byteP)[0] = val.u_uint; |
556 } else { |
558 } else { |
557 byteP[0] = val.u_char[0]; |
559 byteP[0] = val.u_char[0]; |
558 byteP[1] = val.u_char[1]; |
560 byteP[1] = val.u_char[1]; |
559 byteP[2] = val.u_char[2]; |
561 byteP[2] = val.u_char[2]; |
560 byteP[3] = val.u_char[3]; |
562 byteP[3] = val.u_char[3]; |
561 } |
563 } |
562 #endif |
564 #endif |
563 RETURN ( value ); |
565 RETURN ( value ); |
564 } |
566 } |
565 } |
567 } |
566 } |
568 } |
567 error: ; |
569 error: ; |
568 %}. |
570 %}. |
569 ^ super doubleWordAt:index put:value. |
571 ^ super unsignedInt32At:index put:value. |
570 |
572 |
571 " |
573 " |
572 |b| |
574 |b| |
573 b := ByteArray new:4. |
575 b := ByteArray new:4. |
574 b doubleWordAt:1 put:16r04030201. |
576 b unsignedInt32At:1 put:16r04030201. |
575 b inspect |
577 b inspect |
576 " |
578 " |
577 ! |
579 ! |
578 |
580 |
579 doubleWordAt:index put:value MSB:msb |
581 unsignedInt32At:index put:value MSB:msb |
580 "set the 4-bytes starting at index from the (unsigned) Integer value. |
582 "set the 4-bytes starting at index from the (unsigned) Integer value. |
581 The value must be in the range 0 to 16rFFFFFFFF. |
583 The value must be in the range 0 to 16rFFFFFFFF. |
582 The value is stored MSB-first if msb is true; LSB-first otherwise. |
584 The value is stored MSB-first if msb is true; LSB-first otherwise. |
583 question: should it store signed values ? (see ByteArray signedDoubleWordAt:put:)" |
585 question: should it store signed values ? (see ByteArray signedDoubleWordAt:put:)" |
584 |
586 |
591 int val; |
593 int val; |
592 OBJ cls; |
594 OBJ cls; |
593 unsigned char *byteP; |
595 unsigned char *byteP; |
594 |
596 |
595 if (__isSmallInteger(index)) { |
597 if (__isSmallInteger(index)) { |
596 if (__isSmallInteger(value)) { |
598 if (__isSmallInteger(value)) { |
597 val = __intVal(value); |
599 val = __intVal(value); |
598 } else { |
600 } else { |
599 val = __longIntVal(value); |
601 val = __longIntVal(value); |
600 if (val == 0) goto error; |
602 if (val == 0) goto error; |
601 } |
603 } |
602 indx = __intVal(index); |
604 indx = __intVal(index); |
603 if (indx > 0) { |
605 if (indx > 0) { |
604 if ((cls = __qClass(self)) != @global(ByteArray)) |
606 if ((cls = __qClass(self)) != @global(ByteArray)) |
605 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); |
607 indx += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); |
606 nIndex = __qSize(self) - OHDR_SIZE; |
608 nIndex = __qSize(self) - OHDR_SIZE; |
607 if ((indx+3) <= nIndex) { |
609 if ((indx+3) <= nIndex) { |
608 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1; |
610 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1; |
609 if (msb == true) { |
611 if (msb == true) { |
610 /* |
612 /* |
611 * most significant byte first (i.e sparc order) |
613 * most significant byte first (i.e sparc order) |
612 */ |
614 */ |
613 #if defined(__MSBFIRST__) |
615 #if defined(__MSBFIRST__) |
614 if (((INT)byteP & 3) == 0) { |
616 if (((INT)byteP & 3) == 0) { |
615 ((int *)byteP)[0] = val; |
617 ((int *)byteP)[0] = val; |
616 } else |
618 } else |
617 #endif |
619 #endif |
618 { |
620 { |
619 byteP[3] = val & 0xFF; |
621 byteP[3] = val & 0xFF; |
620 val >>= 8; |
622 val >>= 8; |
621 byteP[2] = val & 0xFF; |
623 byteP[2] = val & 0xFF; |
622 val >>= 8; |
624 val >>= 8; |
623 byteP[1] = val & 0xFF; |
625 byteP[1] = val & 0xFF; |
624 val >>= 8; |
626 val >>= 8; |
625 byteP[0] = val & 0xFF; |
627 byteP[0] = val & 0xFF; |
626 } |
628 } |
627 } else { |
629 } else { |
628 /* |
630 /* |
629 * least significant byte first (i.e i386/alpha order) |
631 * least significant byte first (i.e i386/alpha order) |
630 */ |
632 */ |
631 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK)) |
633 #if defined(__i386__) || (defined(__LSBFIRST__) && defined(UNALIGNED_FETCH_OK)) |
632 ((int *)byteP)[0] = val; |
634 ((int *)byteP)[0] = val; |
633 #else |
635 #else |
634 # if defined(__LSBFIRST__) |
636 # if defined(__LSBFIRST__) |
635 if (((unsigned INT)byteP & 3) == 0) { |
637 if (((unsigned INT)byteP & 3) == 0) { |
636 ((int *)byteP)[0] = val; |
638 ((int *)byteP)[0] = val; |
637 } else |
639 } else |
638 # endif |
640 # endif |
639 { |
641 { |
640 byteP[0] = val & 0xFF; |
642 byteP[0] = val & 0xFF; |
641 val >>= 8; |
643 val >>= 8; |
642 byteP[1] = val & 0xFF; |
644 byteP[1] = val & 0xFF; |
643 val >>= 8; |
645 val >>= 8; |
644 byteP[2] = val & 0xFF; |
646 byteP[2] = val & 0xFF; |
645 val >>= 8; |
647 val >>= 8; |
646 byteP[3] = val & 0xFF; |
648 byteP[3] = val & 0xFF; |
647 } |
649 } |
648 #endif |
650 #endif |
649 } |
651 } |
650 RETURN ( value ); |
652 RETURN ( value ); |
651 } |
653 } |
652 } |
654 } |
653 } |
655 } |
654 error: ; |
656 error: ; |
655 %}. |
657 %}. |
656 ^ super doubleWordAt:index put:value MSB:msb |
658 ^ super unsignedInt32At:index put:value MSB:msb |
657 |
659 |
658 " |
660 " |
659 |b| |
661 |b| |
660 b := ByteArray new:8. |
662 b := ByteArray new:8. |
661 b doubleWordAt:1 put:16r04030201 MSB:true. |
663 b unsignedInt32At:1 put:16r04030201 MSB:true. |
662 b doubleWordAt:5 put:16r04030201 MSB:false. |
664 b unsignedInt32At:5 put:16r04030201 MSB:false. |
663 b inspect |
665 b inspect |
664 " |
666 " |
665 ! ! |
667 ! ! |
666 |
668 |
667 !ByteArray methodsFor:'accessing-shorts'! |
669 !ByteArray methodsFor:'accessing-shorts'! |
668 |
670 |
669 wordAt:index |
671 unsignedInt16At:index |
670 "return the 2-bytes starting at index as an (unsigned) Integer. |
672 "return the 2-bytes starting at index as an (unsigned) Integer. |
671 The value is retrieved in the machines natural byte order |
673 The value is retrieved in the machine's natural byte order |
672 Notice: |
674 Notice: |
673 the index is a byte index; thus, this allows for unaligned access to |
675 the index is a byte index; thus, this allows for unaligned access to |
674 words on any boundary. |
676 words on any boundary. |
675 Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)" |
677 Question: should it be retrieve signed values ? (see ByteArray>>signedWordAt:)" |
676 |
678 |
693 if ((indx+1) <= nIndex) { |
695 if ((indx+1) <= nIndex) { |
694 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1; |
696 byteP = (unsigned char *)(__ByteArrayInstPtr(self)->ba_element) + indx - 1; |
695 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK) |
697 #if defined(__i386__) || defined(UNALIGNED_FETCH_OK) |
696 val.u_ushort = ((unsigned short *)byteP)[0]; |
698 val.u_ushort = ((unsigned short *)byteP)[0]; |
697 #else |
699 #else |
698 /* |
700 val.u_char[0] = byteP[0]; |
699 * mhmh to be measured: |
701 val.u_char[1] = byteP[1]; |
700 * the if may hurt more than the additional |
|
701 * memory cycles on some machines ... |
|
702 */ |
|
703 if (((INT)byteP & 1) == 0) { |
|
704 /* aligned */ |
|
705 val.u_ushort = ((unsigned short *)byteP)[0]; |
|
706 } else { |
|
707 val.u_char[0] = byteP[0]; |
|
708 val.u_char[1] = byteP[1]; |
|
709 } |
|
710 #endif |
702 #endif |
711 RETURN ( __mkSmallInteger((val.u_ushort)) ); |
703 RETURN ( __mkSmallInteger((val.u_ushort)) ); |
712 } |
704 } |
713 } |
705 } |
714 } |
706 } |
715 %}. |
707 %}. |
716 ^ super wordAt:index |
708 ^ super unsignedInt16At:index |
717 ! |
709 ! |
718 |
710 |
719 wordAt:index MSB:msb |
711 unsignedInt16At:index MSB:msb |
720 "return the 2-bytes starting at index as an (unsigned) Integer. |
712 "return the 2-bytes starting at index as an (unsigned) Integer. |
721 The value is retrieved MSB (high 8 bits at lower index) if msb is true; |
713 The value is retrieved MSB (high 8 bits at lower index) if msb is true; |
722 LSB-first (i.e. low 8-bits at lower byte index) if its false. |
714 LSB-first (i.e. low 8-bits at lower byte index) if its false. |
723 Notice: |
715 Notice: |
724 the index is a byte index; thus, this allows for unaligned access to |
716 the index is a byte index; thus, this allows for unaligned access to |
786 RETURN ( __mkSmallInteger(val) ); |
778 RETURN ( __mkSmallInteger(val) ); |
787 } |
779 } |
788 } |
780 } |
789 } |
781 } |
790 %}. |
782 %}. |
791 ^ super wordAt:index MSB:msb |
783 ^ super unsignedInt16At:index MSB:msb |
792 ! |
784 ! |
793 |
785 |
794 wordAt:index put:value |
786 unsignedInt16At:index put:value |
795 "set the 2-bytes starting at index from the (unsigned) Integer value. |
787 "set the 2-bytes starting at index from the (unsigned) Integer value. |
796 The stored value must be in the range 0 .. 16rFFFF. |
788 The stored value must be in the range 0 .. 16rFFFF. |
797 The value is stored in the machines natural byteorder, |
789 The value is stored in the machine's natural byteorder, |
798 i.e. this method should only be used to fill byteArrays which are |
790 i.e. this method should only be used to fill byteArrays which are |
799 used internally (not passed to other machines). |
791 used internally (not passed to other machines). |
800 Notice: |
792 Notice: |
801 the index is a byte index; thus, this allows for unaligned access to |
793 the index is a byte index; thus, this allows for unaligned access to |
802 words on any boundary. |
794 words on any boundary. |
843 } |
835 } |
844 } |
836 } |
845 } |
837 } |
846 } |
838 } |
847 %}. |
839 %}. |
848 ^ super wordAt:index put:value |
840 ^ super unsignedInt16At:index put:value |
849 |
841 |
850 " |
842 " |
851 |b| |
843 |b| |
852 b := ByteArray new:4. |
844 b := ByteArray new:4. |
853 b wordAt:1 put:16r0102. |
845 b unsignedInt16At:1 put:16r0102. |
854 b wordAt:3 put:16r0304. |
846 b unsignedInt16At:3 put:16r0304. |
855 b inspect |
847 b inspect |
856 " |
848 " |
857 ! |
849 ! |
858 |
850 |
859 wordAt:index put:value MSB:msb |
851 unsignedInt16At:index put:value MSB:msb |
860 "set the 2-bytes starting at index from the (unsigned) Integer value. |
852 "set the 2-bytes starting at index from the (unsigned) Integer value. |
861 The stored value must be in the range 0 .. 16rFFFF. |
853 The stored value must be in the range 0 .. 16rFFFF. |
862 The value is stored LSB-first (i.e. the low 8bits are stored at the |
854 The value is stored LSB-first (i.e. the low 8bits are stored at the |
863 lower index) if msb is false, MSB-first otherwise. |
855 lower index) if msb is false, MSB-first otherwise. |
864 Notice: |
856 Notice: |