581 CX_TEST_ASSERT(buf.pos == 5); |
581 CX_TEST_ASSERT(buf.pos == 5); |
582 CX_TEST_ASSERT(buf.size == 6); |
582 CX_TEST_ASSERT(buf.size == 6); |
583 CX_TEST_ASSERT(memcmp(buf.space, "tetest__XXXXXXXX", 16) == 0); |
583 CX_TEST_ASSERT(memcmp(buf.space, "tetest__XXXXXXXX", 16) == 0); |
584 TEST_BUFFER_SHIFT_TEARDOWN(buf); |
584 TEST_BUFFER_SHIFT_TEARDOWN(buf); |
585 } |
585 } |
|
586 } |
|
587 |
|
588 static size_t mock_write_limited_rate( |
|
589 void const *ptr, |
|
590 size_t size, |
|
591 __attribute__((unused)) size_t nitems, |
|
592 CxBuffer *buffer |
|
593 ) { |
|
594 // simulate limited target drain capacity |
|
595 static bool full = false; |
|
596 if (full) { |
|
597 full = false; |
|
598 return 0; |
|
599 } else { |
|
600 full = true; |
|
601 return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer); |
|
602 } |
|
603 } |
|
604 |
|
605 CX_TEST(test_buffer_write_size_one_fit) { |
|
606 CxBuffer buf, target; |
|
607 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
608 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
609 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
610 buf.capacity = 8; |
|
611 buf.size = buf.pos = 4; |
|
612 const char *data = "test"; |
|
613 CX_TEST_DO { |
|
614 size_t written = cxBufferWrite(data, 1, 4, &buf); |
|
615 CX_TEST_ASSERT(written == 4); |
|
616 CX_TEST_ASSERT(buf.size == 8); |
|
617 CX_TEST_ASSERT(buf.pos == 8); |
|
618 CX_TEST_ASSERT(buf.capacity == 8); |
|
619 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); |
|
620 } |
|
621 |
|
622 cxBufferDestroy(&buf); |
|
623 cxBufferDestroy(&target); |
|
624 } |
|
625 |
|
626 CX_TEST(test_buffer_write_size_one_discard) { |
|
627 CxBuffer buf, target; |
|
628 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
629 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
630 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
631 buf.capacity = 8; |
|
632 buf.size = buf.pos = 4; |
|
633 const char *data = "testing"; |
|
634 CX_TEST_DO { |
|
635 size_t written = cxBufferWrite(data, 1, 7, &buf); |
|
636 CX_TEST_ASSERT(written == 4); |
|
637 CX_TEST_ASSERT(buf.size == 8); |
|
638 CX_TEST_ASSERT(buf.pos == 8); |
|
639 CX_TEST_ASSERT(buf.capacity == 8); |
|
640 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); |
|
641 } |
|
642 cxBufferDestroy(&buf); |
|
643 cxBufferDestroy(&target); |
|
644 } |
|
645 |
|
646 CX_TEST(test_buffer_write_size_one_extend) { |
|
647 CxBuffer buf, target; |
|
648 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
649 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
650 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
651 buf.capacity = 8; |
|
652 buf.size = buf.pos = 4; |
|
653 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
654 const char *data = "testing"; |
|
655 CX_TEST_DO { |
|
656 size_t written = cxBufferWrite(data, 1, 7, &buf); |
|
657 CX_TEST_ASSERT(written == 7); |
|
658 CX_TEST_ASSERT(buf.size == 11); |
|
659 CX_TEST_ASSERT(buf.pos == 11); |
|
660 CX_TEST_ASSERT(buf.capacity >= 11); |
|
661 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); |
|
662 } |
|
663 cxBufferDestroy(&buf); |
|
664 cxBufferDestroy(&target); |
|
665 } |
|
666 |
|
667 CX_TEST(test_buffer_write_multibyte_fit) { |
|
668 CxBuffer buf, target; |
|
669 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
670 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
671 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
672 buf.capacity = 8; |
|
673 buf.size = buf.pos = 4; |
|
674 const char *data = "test"; |
|
675 CX_TEST_DO { |
|
676 size_t written = cxBufferWrite(data, 2, 2, &buf); |
|
677 CX_TEST_ASSERT(written == 2); |
|
678 CX_TEST_ASSERT(buf.size == 8); |
|
679 CX_TEST_ASSERT(buf.pos == 8); |
|
680 CX_TEST_ASSERT(buf.capacity == 8); |
|
681 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); |
|
682 } |
|
683 cxBufferDestroy(&buf); |
|
684 cxBufferDestroy(&target); |
|
685 } |
|
686 |
|
687 CX_TEST(test_buffer_write_multibyte_discard) { |
|
688 CxBuffer buf, target; |
|
689 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
690 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
691 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
692 buf.capacity = 8; |
|
693 buf.size = 4; |
|
694 buf.pos = 3; |
|
695 const char *data = "testing"; |
|
696 CX_TEST_DO { |
|
697 size_t written = cxBufferWrite(data, 2, 4, &buf); |
|
698 // remember: whole elements are discarded if they do not fit |
|
699 CX_TEST_ASSERT(written == 2); |
|
700 CX_TEST_ASSERT(buf.size == 7); |
|
701 CX_TEST_ASSERT(buf.pos == 7); |
|
702 CX_TEST_ASSERT(buf.capacity == 8); |
|
703 CX_TEST_ASSERT(0 == memcmp(buf.space, "pretest\0", 8)); |
|
704 } |
|
705 cxBufferDestroy(&buf); |
|
706 cxBufferDestroy(&target); |
|
707 } |
|
708 |
|
709 CX_TEST(test_buffer_write_multibyte_extend) { |
|
710 CxBuffer buf, target; |
|
711 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
712 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
713 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
714 buf.capacity = 8; |
|
715 buf.size = 4; |
|
716 buf.pos = 3; |
|
717 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
718 const char *data = "tester"; |
|
719 CX_TEST_DO { |
|
720 size_t written = cxBufferWrite(data, 2, 3, &buf); |
|
721 // remember: whole elements are discarded if they do not fit |
|
722 CX_TEST_ASSERT(written == 3); |
|
723 CX_TEST_ASSERT(buf.size == 9); |
|
724 CX_TEST_ASSERT(buf.pos == 9); |
|
725 CX_TEST_ASSERT(buf.capacity >= 9); |
|
726 CX_TEST_ASSERT(0 == memcmp(buf.space, "pretester", 9)); |
|
727 } |
|
728 cxBufferDestroy(&buf); |
|
729 cxBufferDestroy(&target); |
|
730 } |
|
731 |
|
732 CX_TEST(test_buffer_put_fit) { |
|
733 CxBuffer buf, target; |
|
734 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
735 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
736 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
737 buf.capacity = 8; |
|
738 buf.size = buf.pos = 4; |
|
739 CX_TEST_DO { |
|
740 int c = cxBufferPut(&buf, 0x200 | 'a'); |
|
741 CX_TEST_ASSERT(c == 'a'); |
|
742 CX_TEST_ASSERT(buf.size == 5); |
|
743 CX_TEST_ASSERT(buf.pos == 5); |
|
744 CX_TEST_ASSERT(buf.capacity == 8); |
|
745 CX_TEST_ASSERT(0 == memcmp(buf.space, "prepa\0", 6)); |
|
746 } |
|
747 cxBufferDestroy(&buf); |
|
748 cxBufferDestroy(&target); |
|
749 } |
|
750 |
|
751 CX_TEST(test_buffer_put_discard) { |
|
752 CxBuffer buf, target; |
|
753 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
754 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
755 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
756 buf.capacity = 8; |
|
757 buf.size = 4; |
|
758 buf.pos = 8; |
|
759 CX_TEST_DO { |
|
760 int c = cxBufferPut(&buf, 0x200 | 'a'); |
|
761 CX_TEST_ASSERT(c == EOF); |
|
762 CX_TEST_ASSERT(buf.size == 4); |
|
763 CX_TEST_ASSERT(buf.pos == 8); |
|
764 CX_TEST_ASSERT(buf.capacity == 8); |
|
765 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0\0\0\0\0", 9)); |
|
766 } |
|
767 cxBufferDestroy(&buf); |
|
768 cxBufferDestroy(&target); |
|
769 } |
|
770 |
|
771 CX_TEST(test_buffer_put_extend) { |
|
772 CxBuffer buf, target; |
|
773 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
774 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
775 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
776 buf.capacity = 8; |
|
777 buf.size = 4; |
|
778 buf.pos = 8; |
|
779 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
780 CX_TEST_DO { |
|
781 int c = cxBufferPut(&buf, 0x200 | 'a'); |
|
782 CX_TEST_ASSERT(c == 'a'); |
|
783 CX_TEST_ASSERT(buf.size == 9); |
|
784 CX_TEST_ASSERT(buf.pos == 9); |
|
785 CX_TEST_ASSERT(buf.capacity >= 9); |
|
786 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0\0\0\0a", 9)); |
|
787 } |
|
788 cxBufferDestroy(&buf); |
|
789 cxBufferDestroy(&target); |
|
790 } |
|
791 |
|
792 CX_TEST(test_buffer_put_string_fit) { |
|
793 CxBuffer buf, target; |
|
794 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
795 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
796 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
797 buf.capacity = 8; |
|
798 buf.size = buf.pos = 4; |
|
799 const char *data = "test"; |
|
800 CX_TEST_DO { |
|
801 size_t written = cxBufferPutString(&buf, data); |
|
802 CX_TEST_ASSERT(written == 4); |
|
803 CX_TEST_ASSERT(buf.size == 8); |
|
804 CX_TEST_ASSERT(buf.pos == 8); |
|
805 CX_TEST_ASSERT(buf.capacity == 8); |
|
806 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); |
|
807 } |
|
808 cxBufferDestroy(&buf); |
|
809 cxBufferDestroy(&target); |
|
810 } |
|
811 |
|
812 CX_TEST(test_buffer_put_string_discard) { |
|
813 CxBuffer buf, target; |
|
814 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
815 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
816 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
817 buf.capacity = 8; |
|
818 buf.size = buf.pos = 4; |
|
819 const char *data = "testing"; |
|
820 CX_TEST_DO { |
|
821 size_t written = cxBufferPutString(&buf, data); |
|
822 CX_TEST_ASSERT(written == 4); |
|
823 CX_TEST_ASSERT(buf.size == 8); |
|
824 CX_TEST_ASSERT(buf.pos == 8); |
|
825 CX_TEST_ASSERT(buf.capacity == 8); |
|
826 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); |
|
827 } |
|
828 cxBufferDestroy(&buf); |
|
829 cxBufferDestroy(&target); |
|
830 } |
|
831 |
|
832 CX_TEST(test_buffer_put_string_extend) { |
|
833 CxBuffer buf, target; |
|
834 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
835 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
836 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
837 buf.capacity = 8; |
|
838 buf.size = buf.pos = 4; |
|
839 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
840 const char *data = "testing"; |
|
841 CX_TEST_DO { |
|
842 size_t written = cxBufferPutString(&buf, data); |
|
843 CX_TEST_ASSERT(written == 7); |
|
844 CX_TEST_ASSERT(buf.size == 11); |
|
845 CX_TEST_ASSERT(buf.pos == 11); |
|
846 CX_TEST_ASSERT(buf.capacity >= 11); |
|
847 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); |
|
848 } |
|
849 cxBufferDestroy(&buf); |
|
850 cxBufferDestroy(&target); |
|
851 } |
|
852 |
|
853 CX_TEST(test_buffer_write_size_overflow) { |
|
854 CxBuffer buf, target; |
|
855 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
856 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
857 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
858 buf.capacity = 8; |
|
859 buf.size = buf.pos = 4; |
|
860 const char *data = "testing"; |
|
861 CX_TEST_DO { |
|
862 size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf); |
|
863 CX_TEST_ASSERT(written == 0); |
|
864 CX_TEST_ASSERT(buf.capacity == 8); |
|
865 CX_TEST_ASSERT(buf.pos == 4); |
|
866 CX_TEST_ASSERT(buf.size == 4); |
|
867 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); |
|
868 } |
|
869 cxBufferDestroy(&buf); |
|
870 cxBufferDestroy(&target); |
|
871 } |
|
872 |
|
873 CX_TEST(test_buffer_write_capacity_overflow) { |
|
874 CxBuffer buf, target; |
|
875 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
876 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
877 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
878 buf.capacity = 8; |
|
879 buf.size = buf.pos = 4; |
|
880 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
881 const char *data = "testing"; |
|
882 CX_TEST_DO { |
|
883 size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf); |
|
884 CX_TEST_ASSERT(written == 0); |
|
885 CX_TEST_ASSERT(buf.capacity == 8); |
|
886 CX_TEST_ASSERT(buf.pos == 4); |
|
887 CX_TEST_ASSERT(buf.size == 4); |
|
888 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); |
|
889 } |
|
890 cxBufferDestroy(&buf); |
|
891 cxBufferDestroy(&target); |
|
892 } |
|
893 |
|
894 CX_TEST(test_buffer_write_only_overwrite) { |
|
895 CxBuffer buf, target; |
|
896 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
897 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
898 memcpy(buf.space, "preptest\0\0\0\0\0\0\0\0", 16); |
|
899 buf.capacity = 8; |
|
900 buf.pos = 3; |
|
901 buf.size = 8; |
|
902 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
903 CX_TEST_DO { |
|
904 size_t written = cxBufferWrite("XXX", 2, 2, &buf); |
|
905 CX_TEST_ASSERT(written == 2); |
|
906 CX_TEST_ASSERT(buf.capacity == 8); |
|
907 CX_TEST_ASSERT(buf.size == 8); |
|
908 CX_TEST_ASSERT(buf.pos == 7); |
|
909 CX_TEST_ASSERT(0 == memcmp(buf.space, "preXXX\0t", 8)); |
|
910 } |
|
911 cxBufferDestroy(&buf); |
|
912 cxBufferDestroy(&target); |
|
913 } |
|
914 |
|
915 CX_TEST(test_buffer_write_flush_at_capacity) { |
|
916 CxBuffer buf, target; |
|
917 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
918 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
919 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
920 buf.capacity = 8; |
|
921 buf.size = buf.pos = 4; |
|
922 buf.flush_target = ⌖ |
|
923 buf.flush_func = (cx_write_func)cxBufferWrite; |
|
924 buf.flush_blkmax = 1; |
|
925 CX_TEST_DO { |
|
926 size_t written = cxBufferWrite("foo", 1, 3, &buf); |
|
927 CX_TEST_ASSERT(written == 3); |
|
928 CX_TEST_ASSERT(buf.pos == 7); |
|
929 CX_TEST_ASSERT(buf.size == 7); |
|
930 CX_TEST_ASSERT(target.pos == 0); |
|
931 CX_TEST_ASSERT(target.size == 0); |
|
932 written = cxBufferWrite("hello", 1, 5, &buf); |
|
933 CX_TEST_ASSERT(written == 5); |
|
934 CX_TEST_ASSERT(buf.pos == 0); |
|
935 CX_TEST_ASSERT(buf.size == 0); |
|
936 CX_TEST_ASSERT(buf.capacity == 8); |
|
937 CX_TEST_ASSERT(target.pos == 12); |
|
938 CX_TEST_ASSERT(target.size == 12); |
|
939 CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoohello", 12)); |
|
940 } |
|
941 cxBufferDestroy(&buf); |
|
942 cxBufferDestroy(&target); |
|
943 } |
|
944 |
|
945 CX_TEST(test_buffer_write_flush_at_threshold) { |
|
946 CxBuffer buf, target; |
|
947 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
948 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
949 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
950 buf.capacity = 8; |
|
951 buf.size = buf.pos = 4; |
|
952 buf.flush_target = ⌖ |
|
953 buf.flush_func = (cx_write_func)cxBufferWrite; |
|
954 buf.flush_blkmax = 1; |
|
955 buf.flush_threshold = 12; |
|
956 buf.flags |= CX_BUFFER_AUTO_EXTEND; |
|
957 CX_TEST_DO { |
|
958 size_t written = cxBufferWrite("foobar", 1, 6, &buf); |
|
959 CX_TEST_ASSERT(written == 6); |
|
960 CX_TEST_ASSERT(buf.pos == 10); |
|
961 CX_TEST_ASSERT(buf.size == 10); |
|
962 CX_TEST_ASSERT(buf.capacity >= 10); |
|
963 CX_TEST_ASSERT(buf.capacity <= 12); |
|
964 CX_TEST_ASSERT(target.pos == 0); |
|
965 CX_TEST_ASSERT(target.size == 0); |
|
966 written = cxBufferWrite("hello", 1, 5, &buf); |
|
967 CX_TEST_ASSERT(written == 5); |
|
968 CX_TEST_ASSERT(buf.pos == 0); |
|
969 CX_TEST_ASSERT(buf.size == 0); |
|
970 CX_TEST_ASSERT(buf.capacity <= 12); |
|
971 CX_TEST_ASSERT(target.pos == 15); |
|
972 CX_TEST_ASSERT(target.size == 15); |
|
973 CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoobarhello", 15)); |
|
974 } |
|
975 cxBufferDestroy(&buf); |
|
976 cxBufferDestroy(&target); |
|
977 } |
|
978 |
|
979 CX_TEST(test_buffer_write_flush_rate_limited) { |
|
980 CxBuffer buf, target; |
|
981 cxBufferInit(&target, NULL, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); |
|
982 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
983 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); |
|
984 buf.capacity = 8; |
|
985 buf.size = buf.pos = 4; |
|
986 buf.flush_target = ⌖ |
|
987 buf.flush_blkmax = 1; |
|
988 // limit the rate of the flush function and the capacity of the target |
|
989 buf.flush_func = (cx_write_func) mock_write_limited_rate; |
|
990 target.capacity = 16; |
|
991 target.flags &= ~CX_BUFFER_AUTO_EXTEND; |
|
992 CX_TEST_DO { |
|
993 size_t written = cxBufferWrite("foo", 1, 3, &buf); |
|
994 CX_TEST_ASSERT(written == 3); |
|
995 CX_TEST_ASSERT(buf.pos == 7); |
|
996 CX_TEST_ASSERT(buf.size == 7); |
|
997 CX_TEST_ASSERT(target.pos == 0); |
|
998 CX_TEST_ASSERT(target.size == 0); |
|
999 written = cxBufferWrite("hello, world!", 1, 13, &buf); |
|
1000 // " world!" fits into this buffer, the remaining stuff is flushed out |
|
1001 CX_TEST_ASSERT(written == 13); |
|
1002 CX_TEST_ASSERT(buf.pos == 7); |
|
1003 CX_TEST_ASSERT(buf.size == 7); |
|
1004 CX_TEST_ASSERT(buf.capacity == 8); |
|
1005 CX_TEST_ASSERT(0 == memcmp(buf.space, " world!", 7)); |
|
1006 CX_TEST_ASSERT(target.pos == 13); |
|
1007 CX_TEST_ASSERT(target.size == 13); |
|
1008 CX_TEST_ASSERT(target.capacity == 16); |
|
1009 CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoohello,", 13)); |
|
1010 } |
|
1011 cxBufferDestroy(&buf); |
|
1012 cxBufferDestroy(&target); |
|
1013 } |
|
1014 |
|
1015 CX_TEST(test_buffer_get) { |
|
1016 CxBuffer buf; |
|
1017 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
1018 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); |
|
1019 buf.capacity = 12; |
|
1020 buf.size = 9; |
|
1021 buf.pos = 2; |
|
1022 CX_TEST_DO { |
|
1023 CX_TEST_ASSERT(cxBufferGet(&buf) == 'm'); |
|
1024 CX_TEST_ASSERT(cxBufferGet(&buf) == 'e'); |
|
1025 CX_TEST_ASSERT(cxBufferGet(&buf) == ' '); |
|
1026 CX_TEST_ASSERT(cxBufferGet(&buf) == 'd'); |
|
1027 CX_TEST_ASSERT(buf.pos == 6); |
|
1028 } |
|
1029 cxBufferDestroy(&buf); |
|
1030 } |
|
1031 |
|
1032 CX_TEST(test_buffer_get_eof) { |
|
1033 CxBuffer buf; |
|
1034 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
1035 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); |
|
1036 buf.capacity = 12; |
|
1037 buf.pos = buf.size = 9; |
|
1038 CX_TEST_DO { |
|
1039 CX_TEST_ASSERT(cxBufferGet(&buf) == EOF); |
|
1040 } |
|
1041 cxBufferDestroy(&buf); |
|
1042 } |
|
1043 |
|
1044 CX_TEST(test_buffer_read) { |
|
1045 CxBuffer buf; |
|
1046 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
1047 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); |
|
1048 buf.capacity = 12; |
|
1049 buf.size = 9; |
|
1050 buf.pos = 2; |
|
1051 CX_TEST_DO { |
|
1052 char target[4]; |
|
1053 size_t read = cxBufferRead(&target, 1, 4, &buf); |
|
1054 CX_TEST_ASSERT(read == 4); |
|
1055 CX_TEST_ASSERT(0 == memcmp(&target, "me d", 4)); |
|
1056 CX_TEST_ASSERT(buf.pos == 6); |
|
1057 } |
|
1058 cxBufferDestroy(&buf); |
|
1059 } |
|
1060 |
|
1061 CX_TEST(test_buffer_read_oob) { |
|
1062 CxBuffer buf; |
|
1063 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
1064 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); |
|
1065 buf.capacity = 12; |
|
1066 buf.size = 9; |
|
1067 buf.pos = 6; |
|
1068 CX_TEST_DO { |
|
1069 char target[4]; |
|
1070 size_t read = cxBufferRead(&target, 1, 4, &buf); |
|
1071 CX_TEST_ASSERT(read == 3); |
|
1072 CX_TEST_ASSERT(0 == memcmp(&target, "ata", 3)); |
|
1073 CX_TEST_ASSERT(buf.pos == 9); |
|
1074 } |
|
1075 cxBufferDestroy(&buf); |
|
1076 } |
|
1077 |
|
1078 CX_TEST(test_buffer_read_oob_multibyte) { |
|
1079 CxBuffer buf; |
|
1080 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
1081 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); |
|
1082 buf.capacity = 12; |
|
1083 buf.size = 9; |
|
1084 buf.pos = 6; |
|
1085 CX_TEST_DO { |
|
1086 char target[4]; |
|
1087 target[2] = '\0'; |
|
1088 size_t read = cxBufferRead(&target, 2, 2, &buf); |
|
1089 CX_TEST_ASSERT(read == 1); |
|
1090 CX_TEST_ASSERT(0 == memcmp(&target, "at\0", 3)); |
|
1091 CX_TEST_ASSERT(buf.pos == 8); |
|
1092 } |
|
1093 cxBufferDestroy(&buf); |
|
1094 } |
|
1095 |
|
1096 CX_TEST(test_buffer_read_eof) { |
|
1097 CxBuffer buf; |
|
1098 cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); |
|
1099 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); |
|
1100 buf.capacity = 12; |
|
1101 buf.size = buf.pos = 9; |
|
1102 CX_TEST_DO { |
|
1103 char target[4]; |
|
1104 size_t read = cxBufferRead(&target, 1, 1, &buf); |
|
1105 CX_TEST_ASSERT(read == 0); |
|
1106 CX_TEST_ASSERT(buf.pos == 9); |
|
1107 } |
|
1108 cxBufferDestroy(&buf); |
586 } |
1109 } |
587 |
1110 |
588 CxTestSuite *cx_test_suite_buffer(void) { |
1111 CxTestSuite *cx_test_suite_buffer(void) { |
589 CxTestSuite *suite = cx_test_suite_new("buffer"); |
1112 CxTestSuite *suite = cx_test_suite_new("buffer"); |
590 |
1113 |