159 |
159 |
160 |ret| |
160 |ret| |
161 |
161 |
162 %{ /* NOCONTEXT */ |
162 %{ /* NOCONTEXT */ |
163 |
163 |
164 REGISTER int pos; |
164 REGISTER INT pos; |
165 unsigned ch; |
165 unsigned ch; |
166 OBJ coll, p, l; |
166 OBJ coll, p, l; |
167 |
167 |
168 coll = __INST(collection); |
168 coll = __INST(collection); |
169 p = __INST(position); |
169 p = __INST(position); |
170 l = __INST(readLimit); |
170 l = __INST(readLimit); |
171 |
171 |
172 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
172 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
173 |
173 |
174 pos = __intVal(p); |
174 pos = __intVal(p); |
175 /* make 1-based */ |
175 if (pos >= 0 && pos < __intVal(l)) { |
176 pos = pos + 1; |
|
177 if (pos > 0 && pos <= __intVal(l)) { |
|
178 OBJ cls, ret; |
176 OBJ cls, ret; |
179 |
177 |
180 cls = __qClass(coll); |
178 cls = __qClass(coll); |
181 if (cls == @global(String)) { |
179 if (cls == @global(String)) { |
182 if (pos <= __stringSize(coll)) { |
180 if (pos < __stringSize(coll)) { |
183 ch = __stringVal(coll)[pos-1]; |
181 ch = __stringVal(coll)[pos]; |
184 ret = __MKCHARACTER(ch); |
182 ret = __MKCHARACTER(ch); |
185 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
183 __INST(position) = __mkSmallInteger(pos+1); |
186 RETURN ( ret ); |
184 RETURN ( ret ); |
187 } |
185 } |
188 } else if (cls == @global(ByteArray)) { |
186 } else if (cls == @global(ByteArray)) { |
189 if (pos <= __byteArraySize(coll)) { |
187 if (pos < __byteArraySize(coll)) { |
190 ch = __ByteArrayInstPtr(coll)->ba_element[pos-1]; |
188 ch = __ByteArrayInstPtr(coll)->ba_element[pos]; |
191 ret = __mkSmallInteger(ch); |
189 ret = __mkSmallInteger(ch); |
192 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
190 __INST(position) = __mkSmallInteger(pos+1); |
193 RETURN ( ret ); |
191 RETURN ( ret ); |
194 } |
192 } |
195 } else if (cls == @global(Unicode16String)) { |
193 } else if (cls == @global(Unicode16String)) { |
196 if (pos <= __unicode16StringSize(coll)) { |
194 if (pos < __unicode16StringSize(coll)) { |
197 ch = __Unicode16StringInstPtr(coll)->s_element[pos-1]; |
195 ch = __Unicode16StringInstPtr(coll)->s_element[pos]; |
198 ret = __MKUCHARACTER(ch); |
196 ret = __MKUCHARACTER(ch); |
199 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
197 __INST(position) = __mkSmallInteger(pos+1); |
200 RETURN ( ret ); |
198 RETURN ( ret ); |
201 } |
199 } |
202 } else if (cls == @global(Array)) { |
200 } else if (cls == @global(Array)) { |
203 if (pos <= __arraySize(coll)) { |
201 if (pos < __arraySize(coll)) { |
204 ret = __ArrayInstPtr(coll)->a_element[pos-1]; |
202 ret = __ArrayInstPtr(coll)->a_element[pos]; |
205 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
203 __INST(position) = __mkSmallInteger(pos+1); |
206 RETURN ( ret ); |
204 RETURN ( ret ); |
207 } |
205 } |
208 } |
206 } |
209 } |
207 } |
210 } |
208 } |
211 %}. |
209 %}. |
212 (position >= readLimit) ifTrue:[^ self pastEndRead]. |
210 (position >= readLimit) ifTrue:[^ self pastEndRead]. |
213 ret := collection at:(position + 1). |
|
214 position := position + 1. |
211 position := position + 1. |
|
212 ret := collection at:position. |
215 ^ ret |
213 ^ ret |
216 ! |
214 ! |
217 |
215 |
218 next:count |
216 next:count |
219 "return the next count elements of the stream as aCollection, |
217 "return the next count elements of the stream as aCollection, |
315 |
313 |
316 |ret| |
314 |ret| |
317 |
315 |
318 %{ /* NOCONTEXT */ |
316 %{ /* NOCONTEXT */ |
319 |
317 |
320 REGISTER int pos; |
318 REGISTER INT pos; |
321 unsigned ch; |
319 unsigned ch; |
322 OBJ coll, p, l; |
320 OBJ coll, p, l; |
323 |
321 |
324 coll = __INST(collection); |
322 coll = __INST(collection); |
325 p = __INST(position); |
323 p = __INST(position); |
326 l = __INST(readLimit); |
324 l = __INST(readLimit); |
327 |
325 |
328 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
326 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
329 |
327 |
330 pos = __intVal(p); |
328 pos = __intVal(p); |
331 /* make 1-based */ |
329 if (pos >= 0 && pos < __intVal(l)) { |
332 pos = pos + 1; |
|
333 if (pos > 0 && pos <= __intVal(l)) { |
|
334 OBJ cls, ret; |
330 OBJ cls, ret; |
335 |
331 |
336 cls = __qClass(coll); |
332 cls = __qClass(coll); |
337 if (cls == @global(String)) { |
333 if (cls == @global(String)) { |
338 if (pos <= __stringSize(coll)) { |
334 if (pos < __stringSize(coll)) { |
339 ch = __stringVal(coll)[pos-1]; |
335 ch = __stringVal(coll)[pos]; |
340 ret = __mkSmallInteger(ch); |
336 ret = __mkSmallInteger(ch); |
341 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
337 __INST(position) = __mkSmallInteger(pos+1); |
342 RETURN ( ret ); |
338 RETURN ( ret ); |
343 } |
339 } |
344 } else if (cls == @global(ByteArray)) { |
340 } else if (cls == @global(ByteArray)) { |
345 if (pos <= __byteArraySize(coll)) { |
341 if (pos < __byteArraySize(coll)) { |
346 ch = __ByteArrayInstPtr(coll)->ba_element[pos-1]; |
342 ch = __ByteArrayInstPtr(coll)->ba_element[pos]; |
347 ret = __mkSmallInteger(ch); |
343 ret = __mkSmallInteger(ch); |
348 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
344 __INST(position) = __mkSmallInteger(pos+1); |
349 RETURN ( ret ); |
345 RETURN ( ret ); |
350 } |
346 } |
351 } else if (cls == @global(Array)) { |
347 } else if (cls == @global(Array)) { |
352 if (pos <= __arraySize(coll)) { |
348 if (pos < __arraySize(coll)) { |
353 ret = __ArrayInstPtr(coll)->a_element[pos-1]; |
349 ret = __ArrayInstPtr(coll)->a_element[pos]; |
354 if (!__isSmallInteger(ret) || __intVal(ret) > 255) goto out; |
350 if (!__isSmallInteger(ret) || __intVal(ret) > 255) goto out; |
355 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
351 __INST(position) = __mkSmallInteger(pos+1); |
356 RETURN ( ret ); |
352 RETURN ( ret ); |
357 } |
353 } |
358 } |
354 } |
359 } |
355 } |
360 } |
356 } |
408 Transcript showCR:('n = %1; buffer = <%2>' bindWith:n with:buffer) |
404 Transcript showCR:('n = %1; buffer = <%2>' bindWith:n with:buffer) |
409 " |
405 " |
410 ! |
406 ! |
411 |
407 |
412 nextDecimalInteger |
408 nextDecimalInteger |
413 "read the next integer in radix 10. dont skip whitespace. |
409 "read the next integer in radix 10. |
414 - tuned for speed on String-Streams for faster scanning" |
410 Does NOT skip initial whitespace. |
|
411 The streams elements should be characters. |
|
412 |
|
413 Be careful - this method returns 0 if not positioned on a digit intitially |
|
414 or if the end of the stream is encountered. |
|
415 |
|
416 Tuned for speed on String-Streams for faster scanning" |
415 |
417 |
416 |value nextOne| |
418 |value nextOne| |
417 %{ |
419 %{ |
418 int pos, limit, sz; |
420 INT pos, limit, sz; |
419 REGISTER unsigned char *cp; |
421 REGISTER unsigned char *cp; |
420 REGISTER unsigned ch; |
422 REGISTER unsigned ch; |
421 INT val = 0; |
423 INT val = 0; |
422 OBJ coll, p, l; |
424 OBJ coll, p, l; |
423 |
425 |
473 |
475 |
474 |ret| |
476 |ret| |
475 |
477 |
476 %{ /* NOCONTEXT */ |
478 %{ /* NOCONTEXT */ |
477 |
479 |
478 REGISTER int pos; |
480 REGISTER INT pos; |
479 unsigned ch; |
481 unsigned ch; |
480 OBJ coll, p, l; |
482 OBJ coll, p, l; |
481 |
483 |
482 coll = __INST(collection); |
484 coll = __INST(collection); |
483 p = __INST(position); |
485 p = __INST(position); |
484 l = __INST(readLimit); |
486 l = __INST(readLimit); |
485 |
487 |
486 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
488 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
487 pos = __intVal(p); |
489 pos = __intVal(p); |
488 /* make 1-based */ |
490 if (pos >= 0) { |
489 pos = pos + 1; |
|
490 if (pos > 0) { |
|
491 OBJ cls, ret; |
491 OBJ cls, ret; |
492 |
492 |
493 if (pos > __intVal(l)) { |
493 if (pos >= __intVal(l)) { |
494 RETURN(nil); |
494 RETURN(nil); |
495 } |
495 } |
496 |
496 |
497 cls = __qClass(coll); |
497 cls = __qClass(coll); |
498 if (cls == @global(String)) { |
498 if (cls == @global(String)) { |
499 if (pos <= __stringSize(coll)) { |
499 if (pos < __stringSize(coll)) { |
500 ch = __stringVal(coll)[pos-1]; |
500 ch = __stringVal(coll)[pos]; |
501 ret = __MKCHARACTER(ch); |
501 ret = __MKCHARACTER(ch); |
502 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
502 __INST(position) = __mkSmallInteger(pos + 1); |
503 RETURN ( ret ); |
503 RETURN ( ret ); |
504 } |
504 } |
505 } else if (cls == @global(ByteArray)) { |
505 } else if (cls == @global(ByteArray)) { |
506 if (pos <= __byteArraySize(coll)) { |
506 if (pos < __byteArraySize(coll)) { |
507 ch = __ByteArrayInstPtr(coll)->ba_element[pos-1]; |
507 ch = __ByteArrayInstPtr(coll)->ba_element[pos]; |
508 ret = __mkSmallInteger(ch); |
508 ret = __mkSmallInteger(ch); |
509 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
509 __INST(position) = __mkSmallInteger(pos + 1); |
510 RETURN ( ret ); |
510 RETURN ( ret ); |
511 } |
511 } |
512 } else if (cls == @global(Unicode16String)) { |
512 } else if (cls == @global(Unicode16String)) { |
513 if (pos <= __unicode16StringSize(coll)) { |
513 if (pos < __unicode16StringSize(coll)) { |
514 ch = __Unicode16StringInstPtr(coll)->s_element[pos-1]; |
514 ch = __Unicode16StringInstPtr(coll)->s_element[pos]; |
515 ret = __MKUCHARACTER(ch); |
515 ret = __MKUCHARACTER(ch); |
516 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
516 __INST(position) = __mkSmallInteger(pos + 1); |
517 RETURN ( ret ); |
517 RETURN ( ret ); |
518 } |
518 } |
519 } else if (cls == @global(Array)) { |
519 } else if (cls == @global(Array)) { |
520 if (pos <= __arraySize(coll)) { |
520 if (pos < __arraySize(coll)) { |
521 ret = __ArrayInstPtr(coll)->a_element[pos-1]; |
521 ret = __ArrayInstPtr(coll)->a_element[pos]; |
522 __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
522 __INST(position) = __mkSmallInteger(pos + 1); |
523 RETURN ( ret ); |
523 RETURN ( ret ); |
524 } |
524 } |
525 } |
525 } |
526 } |
526 } |
527 } |
527 } |
528 %}. |
528 %}. |
529 ret := collection at:(position + 1). |
|
530 position := position + 1. |
529 position := position + 1. |
|
530 ret := collection at:position. |
531 ^ ret |
531 ^ ret |
532 ! |
532 ! |
533 |
533 |
534 nextPeek |
534 nextPeek |
535 "advance read pointer return the peek element. |
535 "advance read pointer return the peek element. |
542 coll = __INST(collection); |
542 coll = __INST(collection); |
543 p = __INST(position); |
543 p = __INST(position); |
544 l = __INST(readLimit); |
544 l = __INST(readLimit); |
545 |
545 |
546 if (__isStringLike(coll) && __bothSmallInteger(p, l)) { |
546 if (__isStringLike(coll) && __bothSmallInteger(p, l)) { |
547 REGISTER int pos; |
547 REGISTER INT pos; |
548 unsigned ch; |
548 unsigned ch; |
549 |
549 |
550 pos = __intVal(p); |
550 pos = __intVal(p); |
551 /* make 1-based */ |
551 pos++; |
552 pos = pos + 1; |
|
553 if ((pos > 0) && (pos < __intVal(l)) && (pos < __stringSize(coll))) { |
552 if ((pos > 0) && (pos < __intVal(l)) && (pos < __stringSize(coll))) { |
554 pos = pos + 1; |
553 ch = __stringVal(coll)[pos]; |
555 ch = __stringVal(coll)[pos-1]; |
|
556 pos = pos - 1; |
|
557 __INST(position) = __mkSmallInteger(pos); |
554 __INST(position) = __mkSmallInteger(pos); |
558 RETURN ( __MKCHARACTER(ch) ); |
555 RETURN ( __MKCHARACTER(ch) ); |
559 } |
556 } |
560 } |
557 } |
561 %}. |
558 %}. |
582 l = __INST(readLimit); |
579 l = __INST(readLimit); |
583 |
580 |
584 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
581 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
585 |
582 |
586 pos = __intVal(p); |
583 pos = __intVal(p); |
587 /* make 1-based */ |
584 if ((pos < __intVal(l)) && (pos >= 0)) { |
588 pos = pos + 1; |
|
589 if (pos <= __intVal(l) && pos > 0) { |
|
590 cls = __qClass(coll); |
585 cls = __qClass(coll); |
591 if (cls == @global(String)) { |
586 if (cls == @global(String)) { |
592 if (pos <= __stringSize(coll)) { |
587 if (pos < __stringSize(coll)) { |
593 ch = __stringVal(coll)[pos-1]; |
588 ch = __stringVal(coll)[pos]; |
594 RETURN ( __MKCHARACTER(ch) ); |
589 RETURN ( __MKCHARACTER(ch) ); |
595 } |
590 } |
596 } else if (cls == @global(ByteArray)) { |
591 } else if (cls == @global(ByteArray)) { |
597 if (pos <= __byteArraySize(coll)) { |
592 if (pos < __byteArraySize(coll)) { |
598 ch = __ByteArrayInstPtr(coll)->ba_element[pos-1]; |
593 ch = __ByteArrayInstPtr(coll)->ba_element[pos]; |
599 RETURN ( __mkSmallInteger(ch) ); |
594 RETURN ( __mkSmallInteger(ch) ); |
600 } |
595 } |
601 } else if (cls == @global(Array)) { |
596 } else if (cls == @global(Array)) { |
602 if (pos <= __arraySize(coll)) { |
597 if (pos < __arraySize(coll)) { |
603 RETURN ( __ArrayInstPtr(coll)->a_element[pos-1]); |
598 RETURN ( __ArrayInstPtr(coll)->a_element[pos]); |
604 } |
599 } |
605 } |
600 } |
606 } |
601 } |
607 } |
602 } |
608 %}. |
603 %}. |
629 l = __INST(readLimit); |
624 l = __INST(readLimit); |
630 |
625 |
631 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
626 if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) { |
632 |
627 |
633 pos = __intVal(p); |
628 pos = __intVal(p); |
634 /* make 1-based */ |
629 if ((pos < __intVal(l)) && (pos >= 0)) { |
635 pos = pos + 1; |
|
636 if (pos <= __intVal(l) && pos > 0) { |
|
637 cls = __qClass(coll); |
630 cls = __qClass(coll); |
638 if (cls == @global(String)) { |
631 if (cls == @global(String)) { |
639 if (pos <= __stringSize(coll)) { |
632 if (pos < __stringSize(coll)) { |
640 ch = __stringVal(coll)[pos-1]; |
633 ch = __stringVal(coll)[pos]; |
641 RETURN ( __MKCHARACTER(ch) ); |
634 RETURN ( __MKCHARACTER(ch) ); |
642 } |
635 } |
643 RETURN ( nil ); |
636 RETURN ( nil ); |
644 } else if (cls == @global(ByteArray)) { |
637 } else if (cls == @global(ByteArray)) { |
645 if (pos <= __byteArraySize(coll)) { |
638 if (pos < __byteArraySize(coll)) { |
646 ch = __ByteArrayInstPtr(coll)->ba_element[pos-1]; |
639 ch = __ByteArrayInstPtr(coll)->ba_element[pos]; |
647 RETURN ( __mkSmallInteger(ch) ); |
640 RETURN ( __mkSmallInteger(ch) ); |
648 } |
641 } |
649 RETURN ( nil ); |
642 RETURN ( nil ); |
650 } else if (cls == @global(Array)) { |
643 } else if (cls == @global(Array)) { |
651 if (pos <= __arraySize(coll)) { |
644 if (pos < __arraySize(coll)) { |
652 RETURN ( __ArrayInstPtr(coll)->a_element[pos-1]); |
645 RETURN ( __ArrayInstPtr(coll)->a_element[pos]); |
653 } |
646 } |
654 RETURN ( nil ); |
647 RETURN ( nil ); |
655 } |
648 } |
656 } |
649 } |
657 } |
650 } |
738 l = __INST(readLimit); |
730 l = __INST(readLimit); |
739 |
731 |
740 if (__isStringLike(coll) && __bothSmallInteger(p, l)) { |
732 if (__isStringLike(coll) && __bothSmallInteger(p, l)) { |
741 REGISTER unsigned char *chars; |
733 REGISTER unsigned char *chars; |
742 REGISTER unsigned ch; |
734 REGISTER unsigned ch; |
743 REGISTER int pos; |
735 REGISTER INT pos; |
744 int limit; |
736 INT limit; |
|
737 INT sz; |
745 |
738 |
746 pos = __intVal(p); |
739 pos = __intVal(p); |
747 /* make 1-based */ |
740 /* make 1-based */ |
748 pos = pos + 1; |
741 pos = pos + 1; |
749 if (pos <= 0) { |
742 if (pos <= 0) { |
750 RETURN ( nil ); |
743 RETURN ( nil ); |
751 } |
744 } |
752 |
745 |
753 limit = __intVal(l); |
746 limit = __intVal(l); |
754 if (limit > (__qSize(coll) - OHDR_SIZE)) |
747 sz = __qSize(coll) - OHDR_SIZE; |
755 limit = __qSize(coll) - OHDR_SIZE; |
748 if (limit > sz) |
|
749 limit = sz; |
756 |
750 |
757 chars = (unsigned char *)(__stringVal(coll) + pos - 1); |
751 chars = (unsigned char *)(__stringVal(coll) + pos - 1); |
758 while (pos <= limit) { |
752 while (pos <= limit) { |
759 ch = *chars++; |
753 ch = *chars++; |
760 if (((int)ch > 0x20) |
754 if (((int)ch > 0x20) |
795 |
789 |
796 if (__isStringLike(coll) |
790 if (__isStringLike(coll) |
797 && __isCharacter(anObject) |
791 && __isCharacter(anObject) |
798 && __bothSmallInteger(p, l)) { |
792 && __bothSmallInteger(p, l)) { |
799 REGISTER unsigned char *chars; |
793 REGISTER unsigned char *chars; |
800 REGISTER int pos, limit; |
794 REGISTER INT pos, limit; |
801 unsigned ch; |
795 unsigned ch; |
802 int sz; |
796 INT sz; |
803 |
797 |
804 ch = __intVal(__characterVal(anObject)); |
798 ch = __intVal(__characterVal(anObject)); |
805 if (ch <= 0xFF) { |
799 if (ch <= 0xFF) { |
806 pos = __intVal(p); |
800 pos = __intVal(p); |
807 pos = pos + 1; |
801 pos = pos + 1; |
841 if (__isString(_collection) |
832 if (__isString(_collection) |
842 && __isCharacter(anObject)) { |
833 && __isCharacter(anObject)) { |
843 unsigned int ch = __intVal(__characterVal(anObject)); |
834 unsigned int ch = __intVal(__characterVal(anObject)); |
844 |
835 |
845 if (ch <= 0xFF) { |
836 if (ch <= 0xFF) { |
846 int _startPos = __intVal(__INST(position)); |
837 INT _startPos = __intVal(__INST(position)); |
847 int _endIndex; |
838 INT _endIndex; |
848 char *startPtr = __stringVal(_collection) + _startPos; |
839 char *startPtr = __stringVal(_collection) + _startPos; |
849 char *foundPtr; |
840 char *foundPtr; |
850 OBJ rslt; |
841 OBJ rslt; |
851 |
842 INT nMax; |
|
843 #ifdef __osx__ |
|
844 extern char*memchr(char *, int, long); |
|
845 #endif |
852 _endIndex = __stringSize(_collection); |
846 _endIndex = __stringSize(_collection); |
853 if (__isInteger(__INST(readLimit))) { |
847 if (__isInteger(__INST(readLimit))) { |
854 int _readLimit = __intVal(__INST(readLimit)); |
848 int _readLimit = __intVal(__INST(readLimit)); |
855 |
849 |
856 if (_readLimit < _endIndex) _endIndex = _readLimit; |
850 if (_readLimit < _endIndex) _endIndex = _readLimit; |
857 } |
851 } |
858 |
852 |
859 foundPtr = memchr( startPtr, ch, _endIndex-_startPos); |
853 nMax = _endIndex-_startPos; |
|
854 foundPtr = memchr( startPtr, ch, (long)nMax); |
860 if (foundPtr == 0) { |
855 if (foundPtr == 0) { |
861 // not found |
856 // not found |
862 rslt = __MKSTRING_L(startPtr, _endIndex-_startPos); |
857 rslt = __MKSTRING_L(startPtr, nMax); |
863 __INST(position) = __mkSmallInteger(_endIndex); |
858 __INST(position) = __mkSmallInteger(_endIndex); |
864 } else { |
859 } else { |
|
860 INT n = foundPtr-startPtr; |
|
861 |
865 // found at foundPtr |
862 // found at foundPtr |
866 rslt = __MKSTRING_L(startPtr, foundPtr-startPtr); |
863 rslt = __MKSTRING_L(startPtr, n); |
867 __INST(position) = __mkSmallInteger(_startPos + foundPtr-startPtr + 1); |
864 __INST(position) = __mkSmallInteger(_startPos + n + 1); |
868 } |
865 } |
869 RETURN (rslt); |
866 RETURN (rslt); |
870 } |
867 } |
871 } |
868 } |
872 %}. |
869 %}. |