--- a/ExternalStream.st Thu Feb 05 16:15:38 2015 +0100
+++ b/ExternalStream.st Thu Feb 05 19:16:24 2015 +0100
@@ -1495,16 +1495,19 @@
initDefaultEOLMode
OperatingSystem isUNIXlike ifTrue:[
- "/ unix EOL conventions
- DefaultEOLMode := #nl
+ "/ unix EOL conventions
+ DefaultEOLMode := #nl
] ifFalse:[
- OperatingSystem isVMSlike ifTrue:[
- "/ vms EOL conventions
- DefaultEOLMode := #cr
- ] ifFalse:[
- "/ msdos EOL conventions
- DefaultEOLMode := #crlf
- ]
+ OperatingSystem isVMSlike ifTrue:[
+ "/ vms EOL conventions
+ DefaultEOLMode := #cr
+ ] ifFalse:[
+ "/ msdos EOL conventions
+ "/ msdos uses #crlf. but we keep #nl here,
+ "/ otherwise sending HTTP request over sockets fails
+"/ DefaultEOLMode := #crlf
+ DefaultEOLMode := #nl
+ ]
]
!
@@ -5929,28 +5932,78 @@
}
if (__isStringLike(aCollection)) {
+ char *stringP = __stringVal(aCollection);
len = __stringSize(aCollection);
-#if 0
- if ((__INST(binary) != true)
- && (__INST(eolMode) != @symbol(nl))) {
- // see if there is a nl which needs to be translated; do it in chunks, if so
- if (memchr(__stringVal(aCollection), '\n', len) != NULL) {
+ if (__INST(binary) != true
+ && __INST(eolMode) != nil
+ && __INST(eolMode) != @symbol(nl)
+ && memchr(stringP, '\n', len) != NULL) {
+ // see if there is a \n which needs to be translated,
+ // replace \n if so
+
+ char *end = stringP + len;
+ char *sep = __INST(eolMode) == @symbol(crlf) ? "\r\n" : "\r";
+ int sepLen = strlen(sep);
+ int bufLen;
+ char *buf, *endBuf, *sp, *dp;
+
+ // estimate size of buffer - assume every 4th char is a separator
+ bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
+ buf = (char *)malloc(bufLen);
+ if (buf == 0) {
+ error = __mkSmallInteger(ENOMEM);
goto out;
}
+
+ endBuf = buf + bufLen;
+
+ for (sp = stringP, dp = buf; sp < end; sp++) {
+ if (dp >= endBuf) {
+ char *newBuf;
+
+ bufLen = bufLen + ((bufLen/4) + 1) * sepLen;
+ newBuf = (char *)realloc(buf, bufLen);
+ if (newBuf == 0) {
+ free(buf);
+ error = __mkSmallInteger(ENOMEM);
+ goto out;
+ }
+ endBuf = newBuf + bufLen;
+ dp = newBuf + (dp-buf);
+ buf = newBuf;
+ }
+
+ if (*sp == '\n') {
+ strcpy(dp, sep);
+ dp += sepLen;
+ } else {
+ *dp++ = *sp;
+ }
+ }
+
+ len = dp - buf;
+#ifdef WIN32
+ if ((f == __win32_stdout()) || (f == __win32_stderr())) {
+ cnt = __win32_fwrite(buf, 1, len, f);
+ } else
+#endif
+ {
+ __WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
+ }
+ free(buf);
+ } else { // No EOL conversion needed
+#ifdef WIN32
+ if ((f == __win32_stdout()) || (f == __win32_stderr())) {
+ cnt = __win32_fwrite(stringP, 1, len, f);
+ } else
+#endif
+ {
+ o_offs = stringP - (char *)__InstPtr(aCollection);
+ __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
+ }
}
-#endif
-
-#ifdef WIN32
- if ((f == __win32_stdout()) || (f == __win32_stderr())) {
- cnt = __win32_fwrite(__stringVal(aCollection), 1, len, f);
- } else
-#endif
- {
- o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection);
- __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
- }
- } else {
+ } else { // Not a String
if (__INST(binary) == true) {
INT offs;
@@ -5972,10 +6025,11 @@
o_offs += offs;
__WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs, len, _buffered, __INST(handleType));
}
- } else
+ } else // Not binary mode
goto out;
}
+ // Now check for errors
if (cnt == len) {
if (__isSmallInteger(__INST(position))) {
INT np = __intVal(__INST(position)) + len;
@@ -5987,6 +6041,7 @@
}
RETURN (self);
}
+ fprintf(stderr, "cnt=%d len=%d\n", cnt, len);
error = __mkSmallInteger(__threadErrno);
}
}
@@ -6036,6 +6091,8 @@
RETURN(self);
}
if (__isStringLike(aCollection)) {
+ char *stringP;
+
len = __stringSize(aCollection);
if (iStop > len) {
RETURN(self);
@@ -6043,27 +6100,77 @@
if (iStop > len)
iStop = len;
len = iStop - iStart + 1;
-
-#if 0
- if ((__INST(binary) != true)
- && (__INST(eolMode) != @symbol(nl))) {
- // see if there is a nl which needs to be translated; do it in chunks, if so
- if (memchr(__stringVal(aCollection)+iStart-1, '\n', len) != NULL) {
+ stringP = __stringVal(aCollection) + iStart - 1;
+
+ if (__INST(binary) != true
+ && __INST(eolMode) != nil
+ && __INST(eolMode) != @symbol(nl)
+ && memchr(stringP, '\n', len) != NULL) {
+ // see if there is a \n which needs to be translated,
+ // replace \n if so
+
+ char *end = stringP + len;
+ char *sep = __INST(eolMode) == @symbol(crlf) ? "\r\n" : "\r";
+ int sepLen = strlen(sep);
+ int bufLen;
+ char *buf, *endBuf, *sp, *dp;
+
+ // estimate size of buffer - assume every 4th char is a separator
+ bufLen = (sepLen == 1) ? len : (len + ((len/4) + 1) * sepLen);
+ buf = (char *)malloc(bufLen);
+ if (buf == 0) {
+ error = __mkSmallInteger(ENOMEM);
goto out;
}
+
+ endBuf = buf + bufLen;
+
+ for (sp = stringP, dp = buf; sp < end; sp++) {
+ if (dp >= endBuf) {
+ char *newBuf;
+
+ bufLen = bufLen + ((bufLen/4) + 1) * sepLen;
+ newBuf = (char *)realloc(buf, bufLen);
+ if (newBuf == 0) {
+ free(buf);
+ error = __mkSmallInteger(ENOMEM);
+ goto out;
+ }
+ endBuf = newBuf + bufLen;
+ dp = newBuf + (dp-buf);
+ buf = newBuf;
+ }
+
+ if (*sp == '\n') {
+ strcpy(dp, sep);
+ dp += sepLen;
+ } else {
+ *dp++ = *sp;
+ }
+ }
+
+ len = dp - buf;
+#ifdef WIN32
+ if ((f == __win32_stdout()) || (f == __win32_stderr())) {
+ cnt = __win32_fwrite(buf, 1, len, f);
+ } else
+#endif
+ {
+ __WRITEBYTES__(cnt, f, buf, len, _buffered, __INST(handleType));
+ }
+ free(buf);
+ } else { // No EOL conversion needed
+#ifdef WIN32
+ if ((f == __win32_stdout()) || (f == __win32_stderr())) {
+ cnt = __win32_fwrite(stringP, 1, len, f);
+ } else
+#endif
+ {
+ o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection);
+ __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+iStart-1, len, _buffered, __INST(handleType));
+ }
}
-#endif
-
-#ifdef WIN32
- if ((f == __win32_stdout()) || (f == __win32_stderr())) {
- cnt = __win32_fwrite(__stringVal(aCollection)+iStart-1, 1, len, f);
- } else
-#endif
- {
- o_offs = (char *)__stringVal(aCollection)-(char *)__InstPtr(aCollection);
- __WRITEBYTES_OBJ__(cnt, f, aCollection, o_offs+iStart-1, len, _buffered, __INST(handleType));
- }
- } else {
+ } else { // Not a string
if (__INST(binary) == true) {
int offs;
@@ -6266,11 +6373,11 @@
!ExternalStream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.401 2015-02-05 13:07:09 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.402 2015-02-05 18:16:24 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.401 2015-02-05 13:07:09 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/ExternalStream.st,v 1.402 2015-02-05 18:16:24 stefan Exp $'
! !