+nextOrNil
authorClaus Gittinger <cg@exept.de>
Tue, 25 Jul 2006 16:17:45 +0200
changeset 9457 71a5c4520fba
parent 9456 a600e3c17cb4
child 9458 ea81e322a954
+nextOrNil
ReadStream.st
--- a/ReadStream.st	Tue Jul 25 08:55:36 2006 +0200
+++ b/ReadStream.st	Tue Jul 25 16:17:45 2006 +0200
@@ -415,6 +415,71 @@
     ^ value
 !
 
+nextOrNil
+    "return the next element; advance read pointer.
+     return nil, if there is no next element.
+     - tuned for a bit more speed on String/ByteArray/Array-Streams"
+
+    |ret|
+
+%{  /* NOCONTEXT */
+
+    REGISTER int pos;
+    unsigned ch;
+    OBJ coll, p, l;
+
+    coll = __INST(collection);
+    p = __INST(position);
+    l = __INST(readLimit);
+
+    if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
+        pos = __intVal(p);
+        /* make 1-based */
+        pos = pos + 1 - __intVal( @global(PositionableStream:ZeroPosition));
+        if (pos > 0) {
+            OBJ cls, ret;
+
+            if (pos > __intVal(l)) {
+                RETURN(nil);
+            }
+
+            cls = __qClass(coll);
+            if (cls == @global(String)) {
+                if (pos <= __stringSize(coll)) {
+                    ch = __stringVal(coll)[pos-1];
+                    ret = __MKCHARACTER(ch);
+                    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
+                    RETURN ( ret );
+                }
+            } else if (cls == @global(ByteArray)) {
+                if (pos <= __byteArraySize(coll)) {
+                    ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
+                    ret = __mkSmallInteger(ch);
+                    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
+                    RETURN ( ret );
+                }
+            } else if (cls == @global(Unicode16String)) {
+                if (pos <= __unicode16StringSize(coll)) {
+                    ch = __Unicode16StringInstPtr(coll)->s_element[pos-1];
+                    ret = __MKUCHARACTER(ch);
+                    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
+                    RETURN ( ret );
+                }
+            } else if (cls == @global(Array)) {
+                if (pos <= __arraySize(coll)) {
+                    ret = __ArrayInstPtr(coll)->a_element[pos-1];
+                    __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
+                    RETURN ( ret );
+                }
+            }
+        }
+    }
+%}.
+    ret := collection at:(position + 1 - ZeroPosition).
+    position := position + 1.
+    ^ ret
+!
+
 nextPeek
     "advance read pointer return the peek element.
      this is equivalent to (self next; peek).
@@ -735,5 +800,5 @@
 !ReadStream class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.57 2006-05-08 07:07:39 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.58 2006-07-25 14:17:45 cg Exp $'
 ! !