--- a/ReadStream.st Mon Mar 09 18:46:04 2015 +0100
+++ b/ReadStream.st Mon Mar 09 18:46:37 2015 +0100
@@ -18,6 +18,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
@@ -246,7 +262,9 @@
INT pos, limit, sz;
INT len;
- char buffer[256];
+ char quickBuffer[256];
+ char *buffer = quickBuffer;
+ int bufferSize = sizeof(quickBuffer);
REGISTER unsigned char *cp;
REGISTER unsigned ch;
OBJ coll, p, l;
@@ -256,6 +274,7 @@
l = __INST(readLimit);
if (__isStringLike(coll) && __bothSmallInteger(p, l)) {
+ OBJ retVal;
pos = __intVal(p);
/* make 1-based */
@@ -267,6 +286,7 @@
limit = sz;
cp = __stringVal(coll) + pos - 1;
+ /* skip over non-alphanumeric characters */
for (;;) {
if (pos > limit) break;
ch = *cp;
@@ -279,6 +299,7 @@
pos++;
}
+ /* collect non-alphanumeric characters */
len = 0;
for (;;) {
if (pos > limit) break;
@@ -289,9 +310,16 @@
((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++;
@@ -300,7 +328,14 @@
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 );
}
%}
.
@@ -834,15 +869,13 @@
unsigned int ch = __intVal(__characterVal(anObject));
if (ch <= 0xFF) {
- INT _startPos = __intVal(__INST(position));
- INT _endIndex;
+ int _startPos = __intVal(__INST(position));
+ int _endIndex;
char *startPtr = __stringVal(_collection) + _startPos;
char *foundPtr;
OBJ rslt;
- INT nMax;
-#ifdef __osx__
- extern char*memchr(char *, int, long);
-#endif
+ int nMax;
+
_endIndex = __stringSize(_collection);
if (__isInteger(__INST(readLimit))) {
int _readLimit = __intVal(__INST(readLimit));
@@ -851,16 +884,22 @@
}
nMax = _endIndex-_startPos;
- foundPtr = memchr( startPtr, ch, (long)nMax);
+ foundPtr = (char *)memchr( startPtr, ch, (long)nMax);
if (foundPtr == 0) {
// not found
- rslt = __MKSTRING_L(startPtr, nMax);
+ 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 {
- INT n = foundPtr-startPtr;
+ // found at foundPtr
+ int n = foundPtr-startPtr;
- // found at foundPtr
- rslt = __MKSTRING_L(startPtr, n);
+ 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);
@@ -881,9 +920,9 @@
!ReadStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.78 2014-10-04 20:33:07 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.79 2015-03-09 17:46:37 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.78 2014-10-04 20:33:07 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ReadStream.st,v 1.79 2015-03-09 17:46:37 cg Exp $'
! !