390 |
392 |
391 ^ self readFrom:aStringOrStream radix:radix onError:0 |
393 ^ self readFrom:aStringOrStream radix:radix onError:0 |
392 ! |
394 ! |
393 |
395 |
394 readFrom:aStringOrStream radix:radix onError:exceptionBlock |
396 readFrom:aStringOrStream radix:radix onError:exceptionBlock |
395 "return the next UNSIGNED Integer from the (character-)stream aStream in radix; |
397 "return the next possibly signed Integer from the (character-)stream aStream in radix; |
396 (assumes that the initial XXr has already been read). |
398 (assumes that any initial XXr has already been read). |
397 No whitespace-skipping is done. |
399 No whitespace-skipping is done. |
398 Returns the value of exceptionBlock, if no number is available." |
400 Returns the value of exceptionBlock, if no number is available." |
399 |
401 |
400 |str nextChar value |
402 |str nextChar| |
401 r "{ Class: SmallInteger }" |
|
402 r2 "{ Class: SmallInteger }" |
|
403 r3 "{ Class: SmallInteger }" |
|
404 r4 "{ Class: SmallInteger }" |
|
405 digit1 digit2 digit3 digit4 | |
|
406 |
403 |
407 str := aStringOrStream readStream. |
404 str := aStringOrStream readStream. |
408 |
405 |
409 nextChar := str peekOrNil. |
406 nextChar := str peekOrNil. |
410 (nextChar isNil or:[(value := nextChar digitValueRadix:radix) isNil]) ifTrue:[ |
407 nextChar == $- ifTrue:[ |
411 ^ exceptionBlock value |
408 str next. |
412 ]. |
409 ^ self readUnsignedFrom:str radix:radix sign:-1 onError:exceptionBlock |
413 |
410 ]. |
414 "/ OLD code |
411 ^ self readUnsignedFrom:str radix:radix sign:1 onError:exceptionBlock |
415 "/ [nextChar notNil and:[nextChar isDigitRadix:radix]] whileTrue:[ |
|
416 "/ str next. |
|
417 "/ value := value * radix + nextChar digitValue. |
|
418 "/ nextChar := str peekOrNil. |
|
419 "/ ]. |
|
420 "/ ^ value. |
|
421 |
|
422 "/ the code below does the same, but is much faster, if the |
|
423 "/ converted number is large |
|
424 "/ (requires only half as many LargeInt multiplications and additions) |
|
425 "/ It should not be slower for smallIntegers. |
|
426 |
|
427 r := radix. |
|
428 r2 := r * r. |
|
429 r4 := r2 * r2. |
|
430 |
|
431 [ |
|
432 nextChar := str nextPeekOrNil. |
|
433 nextChar notNil and:[(digit1 := nextChar digitValueRadix:r) notNil] |
|
434 ] whileTrue:[ |
|
435 "/ read 4 chars and pre-compute their value to avoid largeInt operations. |
|
436 |
|
437 nextChar := str nextPeekOrNil. |
|
438 (nextChar isNil or:[(digit2 := nextChar digitValueRadix:r) isNil]) ifTrue:[ |
|
439 ^ (value * r) + digit1. |
|
440 ]. |
|
441 |
|
442 nextChar := str nextPeekOrNil. |
|
443 (nextChar isNil or:[(digit3 := nextChar digitValueRadix:r) isNil]) ifTrue:[ |
|
444 ^ (value * r2) + ((digit1*r) + digit2) . |
|
445 ]. |
|
446 |
|
447 nextChar := str nextPeekOrNil. |
|
448 (nextChar isNil or:[ (digit4 := nextChar digitValueRadix:r) isNil]) ifTrue:[ |
|
449 r3 := r2 * r. |
|
450 ^ (value * r3) + ((((digit1*r) + digit2)*r) + digit3). |
|
451 ]. |
|
452 |
|
453 value := (value * r4) + ((((((digit1*r) + digit2)*r) + digit3)*r) + digit4). |
|
454 ]. |
|
455 ^ value |
|
456 |
412 |
457 " |
413 " |
458 Integer readFrom:(ReadStream on:'12345') radix:10 |
414 Integer readFrom:(ReadStream on:'12345') radix:10 |
459 Integer readFrom:(ReadStream on:'FFFF') radix:16 |
415 Integer readFrom:(ReadStream on:'FFFF') radix:16 |
460 Integer readFrom:(ReadStream on:'1010') radix:2 |
416 Integer readFrom:(ReadStream on:'1010') radix:2 |
805 Integer readFromString:'-1234' radix:10 onError:[nil] - I only read unsigned numbers |
761 Integer readFromString:'-1234' radix:10 onError:[nil] - I only read unsigned numbers |
806 Integer readFromString:' 1234' radix:10 onError:[nil] - I do not skip whitespace |
762 Integer readFromString:' 1234' radix:10 onError:[nil] - I do not skip whitespace |
807 Integer readFromString:'1234 ' radix:10 onError:[nil] - I do not accept anything after the number |
763 Integer readFromString:'1234 ' radix:10 onError:[nil] - I do not accept anything after the number |
808 |
764 |
809 " |
765 " |
|
766 ! |
|
767 |
|
768 readUnsignedFrom:aStringOrStream radix:radix |
|
769 "return the next UNSIGNED Integer from the (character-)stream aStream in radix; |
|
770 (assumes that any initial XXr or sign has already been read). |
|
771 No whitespace-skipping is done. |
|
772 Returns 0 if no number available. |
|
773 |
|
774 NOTICE: |
|
775 This behaves different from the default readFrom:, in returning |
|
776 0 (instead of raising an error) in case no number can be read. |
|
777 It is unclear, if this is the correct behavior (ST-80 does this) |
|
778 - depending on the upcoming ANSI standard, this may change." |
|
779 |
|
780 ^ self readUnsignedFrom:aStringOrStream radix:radix sign:1 onError:0 |
|
781 ! |
|
782 |
|
783 readUnsignedFrom:aStringOrStream radix:radix onError:exceptionBlock |
|
784 "return the next UNSIGNED Integer from the (character-)stream aStream in radix; |
|
785 (assumes that any initial XXr or sign has already been read). |
|
786 No whitespace-skipping is done. |
|
787 Returns the value of exceptionBlock, if no number is available." |
|
788 |
|
789 ^ self readUnsignedFrom:aStringOrStream radix:radix sign:1 onError:exceptionBlock |
|
790 |
|
791 " |
|
792 Integer readUnsignedFrom:(ReadStream on:'12345') radix:10 |
|
793 Integer readUnsignedFrom:(ReadStream on:'FFFF') radix:16 |
|
794 Integer readUnsignedFrom:(ReadStream on:'1010') radix:2 |
|
795 Integer readUnsignedFrom:(ReadStream on:'foobar') radix:10 |
|
796 Integer readUnsignedFrom:(ReadStream on:'foobar') radix:10 onError:nil |
|
797 Integer readUnsignedFrom:'gg' radix:10 onError:0 |
|
798 Integer readUnsignedFrom:'' radix:10 onError:'wrong' |
|
799 |
|
800 |s| |
|
801 s := String new:1000 withAll:$1. |
|
802 Time millisecondsToRun:[ |
|
803 1000 timesRepeat:[ |
|
804 s asInteger |
|
805 ] |
|
806 ] |
|
807 " |
|
808 |
|
809 "Modified: / 14.4.1998 / 19:16:46 / cg" |
|
810 ! |
|
811 |
|
812 readUnsignedFrom:aStringOrStream radix:radix sign:sign |
|
813 "return the next UNSIGNED Integer from the (character-)stream aStream in radix; |
|
814 (assumes that any initial XXr or sign has already been read). |
|
815 No whitespace-skipping is done. |
|
816 Returns 0 if no number available. |
|
817 |
|
818 NOTICE: |
|
819 This behaves different from the default readFrom:, in returning |
|
820 0 (instead of raising an error) in case no number can be read. |
|
821 It is unclear, if this is the correct behavior (ST-80 does this) |
|
822 - depending on the upcoming ANSI standard, this may change." |
|
823 |
|
824 ^ self readUnsignedFrom:aStringOrStream radix:radix sign:sign onError:0 |
|
825 ! |
|
826 |
|
827 readUnsignedFrom:aStringOrStream radix:radix sign:sign onError:exceptionBlock |
|
828 "return the next UNSIGNED Integer from the (character-)stream aStream in radix; |
|
829 (assumes that any initial XXr or sign has already been read). |
|
830 No whitespace-skipping is done. |
|
831 Returns the value of exceptionBlock, if no number is available." |
|
832 |
|
833 |str nextChar value ret |
|
834 r "{ Class: SmallInteger }" |
|
835 r2 "{ Class: SmallInteger }" |
|
836 r3 "{ Class: SmallInteger }" |
|
837 r4 "{ Class: SmallInteger }" |
|
838 digit1 digit2 digit3 digit4 | |
|
839 |
|
840 str := aStringOrStream readStream. |
|
841 |
|
842 nextChar := str peekOrNil. |
|
843 (nextChar isNil or:[(value := nextChar digitValueRadix:radix) isNil]) ifTrue:[ |
|
844 ^ exceptionBlock value |
|
845 ]. |
|
846 |
|
847 "/ OLD code |
|
848 "/ [nextChar notNil and:[nextChar isDigitRadix:radix]] whileTrue:[ |
|
849 "/ str next. |
|
850 "/ value := value * radix + nextChar digitValue. |
|
851 "/ nextChar := str peekOrNil. |
|
852 "/ ]. |
|
853 "/ ^ value. |
|
854 |
|
855 "/ the code below does the same, but is much faster, if the |
|
856 "/ converted number is large |
|
857 "/ (requires only half as many LargeInt multiplications and additions) |
|
858 "/ It should not be slower for smallIntegers. |
|
859 |
|
860 r := radix. |
|
861 r2 := r * r. |
|
862 r4 := r2 * r2. |
|
863 |
|
864 [ |
|
865 nextChar := str nextPeekOrNil. |
|
866 nextChar notNil and:[(digit1 := nextChar digitValueRadix:r) notNil] |
|
867 ] whileTrue:[ |
|
868 "/ read 4 chars and pre-compute their value to avoid largeInt operations. |
|
869 |
|
870 nextChar := str nextPeekOrNil. |
|
871 (nextChar isNil or:[(digit2 := nextChar digitValueRadix:r) isNil]) ifTrue:[ |
|
872 ret := (value * r) + digit1. |
|
873 sign == -1 ifTrue:[^ ret negated]. |
|
874 ^ ret |
|
875 ]. |
|
876 |
|
877 nextChar := str nextPeekOrNil. |
|
878 (nextChar isNil or:[(digit3 := nextChar digitValueRadix:r) isNil]) ifTrue:[ |
|
879 ret := (value * r2) + ((digit1*r) + digit2) . |
|
880 sign == -1 ifTrue:[^ ret negated]. |
|
881 ^ ret |
|
882 ]. |
|
883 |
|
884 nextChar := str nextPeekOrNil. |
|
885 (nextChar isNil or:[ (digit4 := nextChar digitValueRadix:r) isNil]) ifTrue:[ |
|
886 r3 := r2 * r. |
|
887 ret := (value * r3) + ((((digit1*r) + digit2)*r) + digit3). |
|
888 sign == -1 ifTrue:[^ ret negated]. |
|
889 ^ ret |
|
890 ]. |
|
891 |
|
892 value := (value * r4) + ((((((digit1*r) + digit2)*r) + digit3)*r) + digit4). |
|
893 ]. |
|
894 sign == -1 ifTrue:[^ value negated]. |
|
895 ^ value |
|
896 |
|
897 " |
|
898 Integer readFrom:(ReadStream on:'12345') radix:10 |
|
899 Integer readFrom:(ReadStream on:'FFFF') radix:16 |
|
900 Integer readFrom:(ReadStream on:'1010') radix:2 |
|
901 Integer readFrom:(ReadStream on:'foobar') radix:10 |
|
902 Integer readFrom:(ReadStream on:'foobar') radix:10 onError:nil |
|
903 Integer readFrom:'gg' radix:10 onError:0 |
|
904 Integer readFrom:'' radix:10 onError:'wrong' |
|
905 |
|
906 |s| |
|
907 s := String new:1000 withAll:$1. |
|
908 Time millisecondsToRun:[ |
|
909 1000 timesRepeat:[ |
|
910 s asInteger |
|
911 ] |
|
912 ] |
|
913 " |
|
914 |
|
915 "Modified: / 14.4.1998 / 19:16:46 / cg" |
810 ! ! |
916 ! ! |
811 |
917 |
812 !Integer class methodsFor:'Compatibility-Squeak'! |
918 !Integer class methodsFor:'Compatibility-Squeak'! |
813 |
919 |
814 readFrom:aStringOrStream base:aBase |
920 readFrom:aStringOrStream base:aBase |