# HG changeset patch # User Stefan Vogel # Date 1423160184 -3600 # Node ID f0895ae69f6975b7b25ae1c506f8e9c77c8b8c08 # Parent 664ffe1aa68e764db1bb9802550471c316b0c9d5 class: ExternalStream changed: #initDefaultEOLMode #nextPutAll: #nextPutAll:startingAt:to: reenable #crlf end-of-line mode conversions DefaultEOLMode for windows is #nl, for backward and HTTP compatibility diff -r 664ffe1aa68e -r f0895ae69f69 ExternalStream.st --- 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 $' ! !