--- a/ReadStream.st Tue Feb 04 21:09:59 2014 +0100
+++ b/ReadStream.st Wed Apr 01 10:20:10 2015 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
@@ -11,6 +13,8 @@
"
"{ Package: 'stx:libbasic' }"
+"{ NameSpace: Smalltalk }"
+
PositionableStream subclass:#ReadStream
instanceVariableNames:''
classVariableNames:''
@@ -18,6 +22,22 @@
category:'Streams'
!
+!ReadStream primitiveDefinitions!
+%{
+
+#include <stdio.h>
+#define _STDIO_H_INCLUDED_
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#ifdef __osx__
+// missing definition ?
+extern void *memchr( void *, int, size_t);
+#endif
+
+%}
+! !
+
!ReadStream class methodsFor:'documentation'!
copyright
@@ -55,6 +75,33 @@
^ super with:aCollection
! !
+!ReadStream methodsFor:'Compatibility-Squeak'!
+
+next: n into: aCollection startingAt: startIndex
+ "Read n objects into the given collection.
+ Return aCollection or a partial copy if less than
+ n elements have been read."
+
+ | max |
+
+ collection notNil ifTrue:[
+ max := (readLimit - position) min: n.
+ aCollection
+ replaceFrom: startIndex
+ to: startIndex+max-1
+ with: collection
+ startingAt: position+1.
+ position := position + max.
+ max = n
+ ifTrue:[^ aCollection]
+ ifFalse:[^ aCollection copyFrom: 1 to: startIndex+max-1].
+ ].
+
+ ^ super next:n into:aCollection startingAt:startIndex.
+
+
+ "Modified: / 12-09-2010 / 13:06:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
!ReadStream methodsFor:'converting'!
@@ -88,13 +135,13 @@
|t s|
t := 'hello world' asText
- emphasizeFrom:1 to:5 with:#bold;
- emphasizeFrom:7 to:11 with:#italic.
+ emphasizeFrom:1 to:5 with:#bold;
+ emphasizeFrom:7 to:11 with:#italic.
s := t readStream.
[s atEnd] whileFalse:[
- Transcript show:(s emphasis); show:' '.
- Transcript show:''''; show:(s next); showCR:''''.
+ Transcript show:(s emphasis); show:' '.
+ Transcript show:''''; show:(s next); showCR:''''.
].
"
@@ -104,7 +151,7 @@
!ReadStream methodsFor:'queries'!
collectionSize
- "return the overall number of elements in the streamed collection
+ "return the overall number of elements in the streamed collection
(both already read and to be read)."
^ collection size
@@ -161,7 +208,7 @@
%{ /* NOCONTEXT */
- REGISTER int pos;
+ REGISTER INT pos;
unsigned ch;
OBJ coll, p, l;
@@ -171,47 +218,45 @@
if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1;
- if (pos > 0 && pos <= __intVal(l)) {
- OBJ cls, ret;
+ pos = __intVal(p);
+ if (pos >= 0 && pos < __intVal(l)) {
+ OBJ cls, ret;
- 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 );
- }
- }
- }
+ cls = __qClass(coll);
+ if (cls == @global(String)) {
+ if (pos < __stringSize(coll)) {
+ ch = __stringVal(coll)[pos];
+ ret = __MKCHARACTER(ch);
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(ByteArray)) {
+ if (pos < __byteArraySize(coll)) {
+ ch = __ByteArrayInstPtr(coll)->ba_element[pos];
+ ret = __mkSmallInteger(ch);
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(Unicode16String)) {
+ if (pos < __unicode16StringSize(coll)) {
+ ch = __Unicode16StringInstPtr(coll)->s_element[pos];
+ ret = __MKUCHARACTER(ch);
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(Array)) {
+ if (pos < __arraySize(coll)) {
+ ret = __ArrayInstPtr(coll)->a_element[pos];
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ }
+ }
}
%}.
(position >= readLimit) ifTrue:[^ self pastEndRead].
- ret := collection at:(position + 1).
position := position + 1.
+ ret := collection at:position.
^ ret
!
@@ -221,20 +266,20 @@
|answer|
- self contentsSpecies = collection class ifTrue:[
- ((position + count) > readLimit) ifFalse:[
- answer := collection copyFrom:position+1 to:position+count.
- position := position+count.
- ^ answer
- ].
+ self contentsSpecies == collection class ifTrue:[
+ ((position + count) > readLimit) ifFalse:[
+ answer := collection copyFrom:position+1 to:position+count.
+ position := position+count.
+ ^ answer
+ ].
].
^ super next:count
"
#[1 2 3 4 5 6 7 8 9] readStream
- next;
- next:5;
- next.
+ next;
+ next:5;
+ next.
"
!
@@ -246,9 +291,11 @@
%{
/* speedup, if collection is a string */
- int pos, limit, sz;
- int len;
- char buffer[256];
+ INT pos, limit, sz;
+ INT len;
+ char quickBuffer[256];
+ char *buffer = quickBuffer;
+ int bufferSize = sizeof(quickBuffer);
REGISTER unsigned char *cp;
REGISTER unsigned ch;
OBJ coll, p, l;
@@ -258,10 +305,11 @@
l = __INST(readLimit);
if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
+ OBJ retVal;
pos = __intVal(p);
/* make 1-based */
- pos = pos + 1 - __intVal( @global(PositionableStream:ZeroPosition));
+ pos = pos + 1;
limit = __intVal(l);
sz = __qSize(coll) - OHDR_SIZE;
@@ -269,6 +317,7 @@
limit = sz;
cp = __stringVal(coll) + pos - 1;
+ /* skip over non-alphanumeric characters */
for (;;) {
if (pos > limit) break;
ch = *cp;
@@ -281,6 +330,7 @@
pos++;
}
+ /* collect non-alphanumeric characters */
len = 0;
for (;;) {
if (pos > limit) break;
@@ -291,19 +341,32 @@
((ch >= '0') && (ch <= '9'))))
break;
buffer[len++] = ch;
- if (len >= (sizeof(buffer)-1)) {
- /* emergency */
- break;
+ if (len >= (bufferSize-1)) {
+ int newBufferSize = bufferSize * 2;
+
+ if (buffer == quickBuffer) {
+ buffer = (char *)malloc(newBufferSize);
+ memcpy(buffer, quickBuffer, bufferSize);
+ } else {
+ buffer = (char *)realloc(buffer, newBufferSize);
+ }
+ bufferSize = newBufferSize;
}
pos++;
cp++;
}
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
+ pos = pos - 1;
__INST(position) = __mkSmallInteger(pos);
buffer[len] = '\0';
- RETURN ( (len != 0) ? __MKSTRING_L(buffer, len) : nil );
+ if (len == 0) {
+ RETURN (nil);
+ }
+ retVal = __MKSTRING_L(buffer, len);
+ if (buffer != quickBuffer) {
+ free((void *)buffer);
+ }
+ RETURN ( retVal );
}
%}
.
@@ -318,7 +381,7 @@
%{ /* NOCONTEXT */
- REGISTER int pos;
+ REGISTER INT pos;
unsigned ch;
OBJ coll, p, l;
@@ -328,95 +391,61 @@
if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1;
- if (pos > 0 && pos <= __intVal(l)) {
- OBJ cls, ret;
+ pos = __intVal(p);
+ if (pos >= 0 && pos < __intVal(l)) {
+ OBJ cls, ret;
- cls = __qClass(coll);
- if (cls == @global(String)) {
- if (pos <= __stringSize(coll)) {
- ch = __stringVal(coll)[pos-1];
- ret = __mkSmallInteger(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(Array)) {
- if (pos <= __arraySize(coll)) {
- ret = __ArrayInstPtr(coll)->a_element[pos-1];
- if (!__isSmallInteger(ret) || __intVal(ret) > 255) goto out;
- __INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1);
- RETURN ( ret );
- }
- }
- }
+ cls = __qClass(coll);
+ if (cls == @global(String)) {
+ if (pos < __stringSize(coll)) {
+ ch = __stringVal(coll)[pos];
+ ret = __mkSmallInteger(ch);
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(ByteArray)) {
+ if (pos < __byteArraySize(coll)) {
+ ch = __ByteArrayInstPtr(coll)->ba_element[pos];
+ ret = __mkSmallInteger(ch);
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(Array)) {
+ if (pos < __arraySize(coll)) {
+ ret = __ArrayInstPtr(coll)->a_element[pos];
+ if (!__isSmallInteger(ret) || __intVal(ret) > 255) goto out;
+ __INST(position) = __mkSmallInteger(pos+1);
+ RETURN ( ret );
+ }
+ }
+ }
}
out:;
%}.
(position >= readLimit) ifTrue:[^ self pastEndRead].
ret := (collection at:(position + 1)) asInteger.
ret > 255 ifTrue:[
- ret := ConversionError
- raiseRequestWith:self
- errorString:' - #nextByte trying to read a non-byte'.
+ ret := ConversionError
+ raiseRequestWith:self
+ errorString:' - #nextByte trying to read a non-byte'.
].
position := position + 1.
^ ret
!
-nextBytes:numBytes into:aCollection startingAt:initialIndex
- "return the next numBytes from the stream. If the end is
- reached before, only that many bytes are copyied into the
- collection.
- Returns the number of bytes that have been actually read.
- The receiver must support reading of binary bytes.
-
- Notice: this method is provided here for protocol completeness
- with externalStreams - it is normally not used with other
- streams."
+nextDecimalInteger
+ "read the next integer in radix 10.
+ Does NOT skip initial whitespace.
+ The streams elements should be characters.
- ((initialIndex + numBytes - 1) <= aCollection size
- and:[(position + numBytes) <= readLimit
- and:[collection isByteCollection
- and:[aCollection isByteCollection
- ]]]) ifTrue:[
- "do it the fast way"
- aCollection
- replaceBytesFrom:initialIndex to:(initialIndex + numBytes - 1)
- with:collection startingAt:position+1.
- position := position + numBytes.
- ^ numBytes
- ].
- "do it the hard way"
- ^ super nextBytes:numBytes into:aCollection startingAt:initialIndex
+ Be careful - this method returns 0 if not positioned on a digit intitially
+ or if the end of the stream is encountered.
- "
- |s n buffer|
-
- buffer := ByteArray new:10.
-
- s := ReadStream on:#[1 2 3 4 5 6 7 8 9].
- s next:3.
- n := s nextBytes:9 into:buffer startingAt:1.
- Transcript showCR:('n = %1; buffer = <%2>' bindWith:n with:buffer)
- "
-!
-
-nextDecimalInteger
- "read the next integer in radix 10. dont skip whitespace.
- - tuned for speed on String-Streams for faster scanning"
+ Tuned for speed on String-Streams for faster scanning"
|value nextOne|
%{
- int pos, limit, sz;
+ INT pos, limit, sz;
REGISTER unsigned char *cp;
REGISTER unsigned ch;
INT val = 0;
@@ -430,7 +459,7 @@
pos = __intVal(p);
/* make 1-based */
- pos = pos + 1 - __intVal( @global(PositionableStream:ZeroPosition));
+ pos++;
limit = __intVal(l);
sz = __qSize(coll) - OHDR_SIZE;
if (sz < limit)
@@ -447,8 +476,7 @@
if (val > (_MAX_INT / 10)) goto oops;
cp++;
}
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
+ pos--;
__INST(position) = __mkSmallInteger(pos);
RETURN (__mkSmallInteger(val));
}
@@ -477,7 +505,7 @@
%{ /* NOCONTEXT */
- REGISTER int pos;
+ REGISTER INT pos;
unsigned ch;
OBJ coll, p, l;
@@ -486,50 +514,48 @@
l = __INST(readLimit);
if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1;
- if (pos > 0) {
- OBJ cls, ret;
+ pos = __intVal(p);
+ if (pos >= 0) {
+ OBJ cls, ret;
- if (pos > __intVal(l)) {
- RETURN(nil);
- }
+ 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 );
- }
- }
- }
+ cls = __qClass(coll);
+ if (cls == @global(String)) {
+ if (pos < __stringSize(coll)) {
+ ch = __stringVal(coll)[pos];
+ ret = __MKCHARACTER(ch);
+ __INST(position) = __mkSmallInteger(pos + 1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(ByteArray)) {
+ if (pos < __byteArraySize(coll)) {
+ ch = __ByteArrayInstPtr(coll)->ba_element[pos];
+ ret = __mkSmallInteger(ch);
+ __INST(position) = __mkSmallInteger(pos + 1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(Unicode16String)) {
+ if (pos < __unicode16StringSize(coll)) {
+ ch = __Unicode16StringInstPtr(coll)->s_element[pos];
+ ret = __MKUCHARACTER(ch);
+ __INST(position) = __mkSmallInteger(pos + 1);
+ RETURN ( ret );
+ }
+ } else if (cls == @global(Array)) {
+ if (pos < __arraySize(coll)) {
+ ret = __ArrayInstPtr(coll)->a_element[pos];
+ __INST(position) = __mkSmallInteger(pos + 1);
+ RETURN ( ret );
+ }
+ }
+ }
}
%}.
- ret := collection at:(position + 1).
position := position + 1.
+ ret := collection at:position.
^ ret
!
@@ -546,20 +572,16 @@
l = __INST(readLimit);
if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
- REGISTER int pos;
- unsigned ch;
+ REGISTER INT pos;
+ unsigned ch;
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1;
- if ((pos > 0) && (pos < __intVal(l)) && (pos < __stringSize(coll))) {
- pos = pos + 1;
- ch = __stringVal(coll)[pos-1];
- /* make ZeroPosition-based */
- pos = pos - 1;
- __INST(position) = __mkSmallInteger(pos);
- RETURN ( __MKCHARACTER(ch) );
- }
+ pos = __intVal(p);
+ pos++;
+ if ((pos > 0) && (pos < __intVal(l)) && (pos < __stringSize(coll))) {
+ ch = __stringVal(coll)[pos];
+ __INST(position) = __mkSmallInteger(pos);
+ RETURN ( __MKCHARACTER(ch) );
+ }
}
%}.
(position >= readLimit) ifTrue:[^ self pastEndRead].
@@ -575,7 +597,7 @@
%{ /* NOCONTEXT */
- REGISTER int pos;
+ REGISTER INT pos;
unsigned ch;
OBJ coll;
OBJ cls, p, l;
@@ -586,27 +608,25 @@
if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1;
- if (pos <= __intVal(l) && pos > 0) {
- cls = __qClass(coll);
- if (cls == @global(String)) {
- if (pos <= __stringSize(coll)) {
- ch = __stringVal(coll)[pos-1];
- RETURN ( __MKCHARACTER(ch) );
- }
- } else if (cls == @global(ByteArray)) {
- if (pos <= __byteArraySize(coll)) {
- ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
- RETURN ( __mkSmallInteger(ch) );
- }
- } else if (cls == @global(Array)) {
- if (pos <= __arraySize(coll)) {
- RETURN ( __ArrayInstPtr(coll)->a_element[pos-1]);
- }
- }
- }
+ pos = __intVal(p);
+ if ((pos < __intVal(l)) && (pos >= 0)) {
+ cls = __qClass(coll);
+ if (cls == @global(String)) {
+ if (pos < __stringSize(coll)) {
+ ch = __stringVal(coll)[pos];
+ RETURN ( __MKCHARACTER(ch) );
+ }
+ } else if (cls == @global(ByteArray)) {
+ if (pos < __byteArraySize(coll)) {
+ ch = __ByteArrayInstPtr(coll)->ba_element[pos];
+ RETURN ( __mkSmallInteger(ch) );
+ }
+ } else if (cls == @global(Array)) {
+ if (pos < __arraySize(coll)) {
+ RETURN ( __ArrayInstPtr(coll)->a_element[pos]);
+ }
+ }
+ }
}
%}.
(position >= readLimit) ifTrue:[^ self pastEndRead].
@@ -622,7 +642,7 @@
%{ /* NOCONTEXT */
- REGISTER int pos;
+ REGISTER INT pos;
unsigned ch;
OBJ coll;
OBJ cls, p, l;
@@ -633,30 +653,28 @@
if (__isNonNilObject(coll) && __bothSmallInteger(p, l)) {
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1;
- if (pos <= __intVal(l) && pos > 0) {
- cls = __qClass(coll);
- if (cls == @global(String)) {
- if (pos <= __stringSize(coll)) {
- ch = __stringVal(coll)[pos-1];
- RETURN ( __MKCHARACTER(ch) );
- }
- RETURN ( nil );
- } else if (cls == @global(ByteArray)) {
- if (pos <= __byteArraySize(coll)) {
- ch = __ByteArrayInstPtr(coll)->ba_element[pos-1];
- RETURN ( __mkSmallInteger(ch) );
- }
- RETURN ( nil );
- } else if (cls == @global(Array)) {
- if (pos <= __arraySize(coll)) {
- RETURN ( __ArrayInstPtr(coll)->a_element[pos-1]);
- }
- RETURN ( nil );
- }
- }
+ pos = __intVal(p);
+ if ((pos < __intVal(l)) && (pos >= 0)) {
+ cls = __qClass(coll);
+ if (cls == @global(String)) {
+ if (pos < __stringSize(coll)) {
+ ch = __stringVal(coll)[pos];
+ RETURN ( __MKCHARACTER(ch) );
+ }
+ RETURN ( nil );
+ } else if (cls == @global(ByteArray)) {
+ if (pos < __byteArraySize(coll)) {
+ ch = __ByteArrayInstPtr(coll)->ba_element[pos];
+ RETURN ( __mkSmallInteger(ch) );
+ }
+ RETURN ( nil );
+ } else if (cls == @global(Array)) {
+ if (pos < __arraySize(coll)) {
+ RETURN ( __ArrayInstPtr(coll)->a_element[pos]);
+ }
+ RETURN ( nil );
+ }
+ }
}
%}.
(position >= readLimit) ifTrue:[^ nil].
@@ -678,13 +696,13 @@
if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
REGISTER unsigned char *chars;
REGISTER unsigned ch;
- REGISTER int pos;
- int limit;
- int sz;
+ REGISTER INT pos;
+ INT limit;
+ INT sz;
pos = __intVal(p);
/* make 1-based */
- pos = pos + 1 - __intVal( @global(PositionableStream:ZeroPosition));
+ pos++;
if (pos <= 0) {
RETURN ( nil );
}
@@ -697,7 +715,6 @@
chars = (unsigned char *)(__stringVal(coll) + pos - 1);
while (pos <= limit) {
- pos++;
ch = *chars++;
if ((ch > 0x20)
|| ((ch != ' ')
@@ -706,14 +723,12 @@
&& (ch != '\n')
&& (ch != '\f')
&& (ch != 0x0B))) {
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
__INST(position) = __mkSmallInteger(pos-1);
RETURN ( __MKCHARACTER(ch) );
}
+ pos++;
}
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
+ pos--;
__INST(position) = __mkSmallInteger(pos);
RETURN ( nil );
}
@@ -745,19 +760,21 @@
if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
REGISTER unsigned char *chars;
REGISTER unsigned ch;
- REGISTER int pos;
- int limit;
+ REGISTER INT pos;
+ INT limit;
+ INT sz;
pos = __intVal(p);
/* make 1-based */
- pos = pos + 1 - __intVal( @global(PositionableStream:ZeroPosition));
+ pos = pos + 1;
if (pos <= 0) {
RETURN ( nil );
}
limit = __intVal(l);
- if (limit > (__qSize(coll) - OHDR_SIZE))
- limit = __qSize(coll) - OHDR_SIZE;
+ sz = __qSize(coll) - OHDR_SIZE;
+ if (limit > sz)
+ limit = sz;
chars = (unsigned char *)(__stringVal(coll) + pos - 1);
while (pos <= limit) {
@@ -769,15 +786,13 @@
&& (ch != '\f')
&& (ch != '\b')
&& (ch != 0x0B))) {
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
+ pos--;
__INST(position) = __mkSmallInteger(pos);
RETURN ( __MKCHARACTER(ch) );
}
pos++;
}
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
+ pos--;
__INST(position) = __mkSmallInteger(pos);
RETURN ( nil );
}
@@ -804,42 +819,87 @@
&& __isCharacter(anObject)
&& __bothSmallInteger(p, l)) {
REGISTER unsigned char *chars;
- REGISTER int pos, limit;
+ REGISTER INT pos, limit;
unsigned ch;
- int sz;
+ INT sz;
+
+ ch = __intVal(__characterVal(anObject));
+ if (ch <= 0xFF) {
+ pos = __intVal(p);
+ pos = pos + 1;
+ if (pos <= 0) {
+ RETURN ( nil );
+ }
- pos = __intVal(p);
- /* make 1-based */
- pos = pos + 1 - __intVal( @global(PositionableStream:ZeroPosition));
- if (pos <= 0) {
+ limit = __intVal(l);
+ sz = __stringSize(coll);
+ if (limit > sz) limit = sz;
+
+ chars = (unsigned char *)(__stringVal(coll) + pos - 1);
+ while (pos < limit) {
+ if (*chars == ch) {
+ ch = *++chars;
+ __INST(position) = __mkSmallInteger(pos);
+ RETURN ( self );
+ }
+ chars++;
+ pos++;
+ }
+ __INST(position) = __mkSmallInteger(pos);
RETURN ( nil );
}
-
- limit = __intVal(l);
- sz = __stringSize(coll);
- if (limit > sz) limit = sz;
-
- chars = (unsigned char *)(__stringVal(coll) + pos - 1);
- ch = __intVal(__characterVal(anObject)) & 0xFF;
- while (pos < limit) {
- if (*chars == ch) {
- ch = *++chars;
- pos++;
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
- __INST(position) = __mkSmallInteger(pos);
- RETURN ( self );
- }
- chars++;
- pos++;
- }
- /* make ZeroPosition-based */
- pos = pos - 1 + __intVal( @global(PositionableStream:ZeroPosition));
- __INST(position) = __mkSmallInteger(pos+1);
- RETURN ( nil );
}
%}.
^ super skipThrough:anObject
+!
+
+upTo:anObject
+%{
+ OBJ _collection = __INST(collection);
+
+ if (__isString(_collection)
+ && __isCharacter(anObject)) {
+ unsigned int ch = __intVal(__characterVal(anObject));
+
+ if (ch <= 0xFF) {
+ int _startPos = __intVal(__INST(position));
+ int _endIndex;
+ char *startPtr = __stringVal(_collection) + _startPos;
+ char *foundPtr;
+ OBJ rslt;
+ int nMax;
+
+ _endIndex = __stringSize(_collection);
+ if (__isInteger(__INST(readLimit))) {
+ int _readLimit = __intVal(__INST(readLimit));
+
+ if (_readLimit < _endIndex) _endIndex = _readLimit;
+ }
+
+ nMax = _endIndex-_startPos;
+ foundPtr = (char *)memchr( startPtr, ch, (long)nMax);
+ if (foundPtr == 0) {
+ // not found
+ rslt = __MKEMPTYSTRING(nMax);
+ // refetch - may GC
+ _collection = __INST(collection);
+ memcpy((void *)__stringVal(rslt), (void *)(__stringVal(_collection) + _startPos), (size_t)nMax);
+ __INST(position) = __mkSmallInteger(_endIndex);
+ } else {
+ // found at foundPtr
+ int n = foundPtr-startPtr;
+
+ rslt = __MKEMPTYSTRING(n);
+ // refetch - may GC
+ _collection = __INST(collection);
+ memcpy((void *)__stringVal(rslt), (void *)(__stringVal(_collection) + _startPos), (size_t)n);
+ __INST(position) = __mkSmallInteger(_startPos + n + 1);
+ }
+ RETURN (rslt);
+ }
+ }
+%}.
+ ^ super upTo:anObject
! !
!ReadStream methodsFor:'writing'!
@@ -853,10 +913,10 @@
!ReadStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.73 2013-12-02 19:06:35 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.81 2015-03-12 19:25:11 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.73 2013-12-02 19:06:35 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.81 2015-03-12 19:25:11 stefan Exp $'
! !