diff options
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c')
| -rw-r--r-- | gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c | 630 |
1 files changed, 437 insertions, 193 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c index c05af1fa255..f214b536966 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c @@ -10,13 +10,11 @@ ** */ -#include "HTUtils.h" -#include "tcp.h" -#include "HTAccess.h" +#include <HTUtils.h> /* Implements: */ -#include "HTFormat.h" +#include <HTFormat.h> PUBLIC float HTMaxSecs = 1e10; /* No effective limit */ PUBLIC float HTMaxLength = 1e10; /* No effective limit */ @@ -31,29 +29,25 @@ PUBLIC long int HTMaxBytes = 0; /* No effective limit */ #endif /* NeXT */ #endif /* unix */ -#include "HTML.h" -#include "HTMLDTD.h" -#include "HText.h" -#include "HTAlert.h" -#include "HTList.h" -#include "HTInit.h" -#include "HTTCP.h" +#include <HTML.h> +#include <HTMLDTD.h> +#include <HText.h> +#include <HTAlert.h> +#include <HTList.h> +#include <HTInit.h> +#include <HTTCP.h> /* Streams and structured streams which we use: */ -#include "HTFWriter.h" -#include "HTPlain.h" -#include "SGML.h" -#include "HTML.h" -#include "HTMLGen.h" +#include <HTFWriter.h> +#include <HTPlain.h> +#include <SGML.h> +#include <HTMLGen.h> -#include "LYexit.h" -#include "LYUtils.h" -#include "LYGlobalDefs.h" -#include "LYLeaks.h" - -#define FREE(x) if (x) {free(x); x = NULL;} - -extern int HTCheckForInterrupt NOPARAMS; +#include <LYexit.h> +#include <LYUtils.h> +#include <GridText.h> +#include <LYGlobalDefs.h> +#include <LYLeaks.h> PUBLIC BOOL HTOutputSource = NO; /* Flag: shortcut parser to stdout */ /* extern BOOL interactive; LJM */ @@ -81,7 +75,9 @@ PUBLIC HTPresentation * default_presentation = NULL; /* * To free off the presentation list. */ +#ifdef LY_FIND_LEAKS PRIVATE void HTFreePresentations NOPARAMS; +#endif /* Define a presentation system command for a content-type ** ------------------------------------------------------- @@ -100,7 +96,7 @@ PUBLIC void HTSetPresentation ARGS6( pres->rep = HTAtom_for(representation); pres->rep_out = WWW_PRESENT; /* Fixed for now ... :-) */ - pres->converter = HTSaveAndExecute; /* Fixed for now ... */ + pres->converter = HTSaveAndExecute; /* Fixed for now ... */ pres->quality = quality; pres->secs = secs; pres->secs_per_byte = secs_per_byte; @@ -114,7 +110,9 @@ PUBLIC void HTSetPresentation ARGS6( */ if (!HTPresentations) { HTPresentations = HTList_new(); +#ifdef LY_FIND_LEAKS atexit(HTFreePresentations); +#endif } if (strcmp(representation, "*")==0) { @@ -157,12 +155,15 @@ PUBLIC void HTSetConversion ARGS7( */ if (!HTPresentations) { HTPresentations = HTList_new(); +#ifdef LY_FIND_LEAKS atexit(HTFreePresentations); +#endif } HTList_addObject(HTPresentations, pres); } +#ifdef LY_FIND_LEAKS /* ** Purpose: Free the presentation list. ** Arguments: void @@ -195,6 +196,7 @@ PRIVATE void HTFreePresentations NOARGS HTList_delete(HTPresentations); HTPresentations = NULL; } +#endif /* LY_FIND_LEAKS */ /* File buffering ** -------------- @@ -223,7 +225,7 @@ PUBLIC void HTInitInput ARGS1 (int,file_number) } PUBLIC int interrupted_in_htgetcharacter = 0; -PUBLIC char HTGetCharacter NOARGS +PUBLIC int HTGetCharacter NOARGS { char ch; interrupted_in_htgetcharacter = 0; @@ -233,18 +235,15 @@ PUBLIC char HTGetCharacter NOARGS input_buffer, INPUT_BUFFER_SIZE); if (status <= 0) { if (status == 0) - return (char)EOF; + return EOF; if (status == HT_INTERRUPTED) { - if (TRACE) - fprintf(stderr, - "HTFormat: Interrupted in HTGetCharacter\n"); + CTRACE(tfp, "HTFormat: Interrupted in HTGetCharacter\n"); interrupted_in_htgetcharacter = 1; - return (char)EOF; + return EOF; } - if (TRACE) - fprintf(stderr, "HTFormat: File read error %d\n", status); - return (char)EOF; /* -1 is returned by UCX - at end of HTTP link */ + CTRACE(tfp, "HTFormat: File read error %d\n", status); + return EOF; /* -1 is returned by UCX + at end of HTTP link */ } input_pointer = input_buffer; input_limit = input_buffer + status; @@ -252,7 +251,7 @@ PUBLIC char HTGetCharacter NOARGS ch = *input_pointer++; } while (ch == (char) 13); /* Ignore ASCII carriage return */ - return FROMASCII(ch); + return FROMASCII((unsigned char)ch); } /* Match maintype to any MIME type starting with maintype, @@ -266,9 +265,8 @@ PRIVATE int half_match ARGS2(char *,trial_type, char *,target) if (!cp || *(cp+1) != '*') return 0; - if (TRACE) - fprintf(stderr,"HTFormat: comparing %s and %s for half match\n", - trial_type, target); + CTRACE(tfp, "HTFormat: comparing %s and %s for half match\n", + trial_type, target); /* main type matches */ if (!strncmp(trial_type, target, (cp-trial_type)-1)) @@ -295,9 +293,7 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( { HTAtom * wildcard = HTAtom_for("*"); - if (TRACE) - fprintf(stderr, - "HTFormat: Looking up presentation for %s to %s\n", + CTRACE(tfp, "HTFormat: Looking up presentation for %s to %s\n", HTAtom_name(rep_in), HTAtom_name(rep_out)); /* don't do anymore do it in the Lynx code at startup LJM */ @@ -316,9 +312,7 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( pres = (HTPresentation *)HTList_objectAt(HTPresentations, i); if (pres->rep == rep_in) { if (pres->rep_out == rep_out) { - if (TRACE) - fprintf(stderr, - "FindPresentation: found exact match: %s\n", + CTRACE(tfp, "FindPresentation: found exact match: %s\n", HTAtom_name(pres->rep)); return pres; @@ -328,9 +322,7 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( if (!strong_wildcard_match) strong_wildcard_match = pres; /* otherwise use the first one */ - if (TRACE) - fprintf(stderr, - "StreamStack: found strong wildcard match: %s\n", + CTRACE(tfp, "StreamStack: found strong wildcard match: %s\n", HTAtom_name(pres->rep)); } @@ -343,9 +335,7 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( if (!strong_subtype_wildcard_match) strong_subtype_wildcard_match = pres; /* otherwise use the first one */ - if (TRACE) - fprintf(stderr, - "StreamStack: found strong subtype wildcard match: %s\n", + CTRACE(tfp, "StreamStack: found strong subtype wildcard match: %s\n", HTAtom_name(pres->rep)); } } @@ -355,9 +345,7 @@ PRIVATE HTPresentation * HTFindPresentation ARGS3( if (!weak_wildcard_match) weak_wildcard_match = pres; /* otherwise use the first one */ - if (TRACE) - fprintf(stderr, - "StreamStack: found weak wildcard match: %s\n", + CTRACE(tfp, "StreamStack: found weak wildcard match: %s\n", HTAtom_name(pres->rep_out)); } if (pres->rep_out == wildcard) { @@ -403,9 +391,7 @@ PUBLIC HTStream * HTStreamStack ARGS4( HTPresentation temp; HTPresentation *match; - if (TRACE) - fprintf(stderr, - "HTFormat: Constructing stream stack for %s to %s\n", + CTRACE(tfp, "HTFormat: Constructing stream stack for %s to %s\n", HTAtom_name(rep_in), HTAtom_name(rep_out)); /* don't return on WWW_SOURCE some people might like @@ -419,13 +405,9 @@ PUBLIC HTStream * HTStreamStack ARGS4( if ((match = HTFindPresentation(rep_in, rep_out, &temp))) { if (match == &temp) { - if (TRACE) - fprintf(stderr, - "StreamStack: Using %s\n", HTAtom_name(temp.rep_out)); + CTRACE(tfp, "StreamStack: Using %s\n", HTAtom_name(temp.rep_out)); } else { - if (TRACE) - fprintf(stderr, - "StreamStack: found exact match: %s\n", + CTRACE(tfp, "StreamStack: found exact match: %s\n", HTAtom_name(match->rep)); } return (*match->converter)(match, anchor, sink); @@ -466,9 +448,7 @@ PUBLIC float HTStackValue ARGS4( { HTAtom * wildcard = HTAtom_for("*"); - if (TRACE) - fprintf(stderr, - "HTFormat: Evaluating stream stack for %s worth %.3f to %s\n", + CTRACE(tfp, "HTFormat: Evaluating stream stack for %s worth %.3f to %s\n", HTAtom_name(rep_in), initial_value, HTAtom_name(rep_out)); if (rep_out == WWW_SOURCE || rep_out == rep_in) @@ -498,16 +478,112 @@ PUBLIC float HTStackValue ARGS4( } +/* Display the page while transfer in progress +** ------------------------------------------- +** +** Repaint the page only when necessary. +** This is a traverse call for HText_pageDisplay() - it works!. +** +*/ +PUBLIC void HTDisplayPartial NOARGS +{ +#ifdef DISP_PARTIAL + if (display_partial) { + /* + ** HText_getNumOfLines() = "current" number of lines received + ** NumOfLines_partial = number of lines at the moment of last repaint. + ** + ** We update NumOfLines_partial only when we repaint the display. + ** -1 is the special value: + ** This is a synchronization flag switched to 0 when HText_new() + ** starts a new HTMainText object - all HText_ functions use it, + ** lines counter in particular [we call it from HText_getNumOfLines()]. + ** + ** Otherwise HTMainText holds info from the previous document + ** and we may repaint it instead of the new one: + ** prev doc scrolled to the first line (=Newline_partial) + ** is not good looking :-) 23 Aug 1998 Leonid Pauzner + ** + ** So repaint the page only when necessary: + */ + if ((NumOfLines_partial != -1) + /* new HText object available */ + && ((Newline_partial + display_lines) > NumOfLines_partial) + /* current page not complete... */ + && (partial_threshold > 0 ? + ((Newline_partial + partial_threshold) < HText_getNumOfLines()) : + ((Newline_partial + display_lines) < HText_getNumOfLines())) + /* + * Originally we rendered by increments of 2 lines, + * but that got annoying on slow network connections. + * Then we switched to full-pages. Now it's configurable. + * If partial_threshold <= 0, then it's a full page + */ + ) { + NumOfLines_partial = HText_getNumOfLines(); + HText_pageDisplay(Newline_partial, ""); + } + } +#else /* nothing */ +#endif /* DISP_PARTIAL */ +} + +/* Put this as early as possible, OK just after HTDisplayPartial() */ +PUBLIC void HTFinishDisplayPartial NOARGS +{ +#ifdef DISP_PARTIAL + if (display_partial) { + /* + * Override Newline with a new value if user + * scrolled the document while downloading. + */ + if (Newline_partial != Newline + && NumOfLines_partial > 0) + Newline = Newline_partial; + } + + /* + * End of incremental rendering stage here. + */ + display_partial = FALSE; + NumOfLines_partial = -1; /* initialize to -1 */ + /* -1 restrict HTDisplayPartial() */ + /* until HText_new() start next HTMainText */ + /* and set the flag to 0 */ +#endif /* DISP_PARTIAL */ +} + /* Push data from a socket down a stream ** ------------------------------------- ** ** This routine is responsible for creating and PRESENTING any ** graphic (or other) objects described by the file. ** -** The file number given is assumed to be a TELNET stream ie containing +** The file number given is assumed to be a TELNET stream, i.e., containing ** CRLF at the end of lines which need to be stripped to LF for unix ** when the format is textual. ** +** State of socket and target stream on entry: +** socket (file_number) assumed open, +** target (sink) assumed valid. +** +** Return values: +** HT_INTERRUPTED Interruption or error after some data received. +** -2 Unexpected disconnect before any data received. +** -1 Interruption or error before any data received, or +** (UNIX) other read error before any data received, or +** download cancelled. +** HT_LOADED Normal close of socket (end of file indication +** received), or +** unexpected disconnect after some data received, or +** other read error after some data received, or +** (not UNIX) other read error before any data received. +** +** State of socket and target stream on return depends on return value: +** HT_INTERRUPTED socket still open, target aborted. +** -2 socket still open, target stream still valid. +** -1 socket still open, target aborted. +** otherwise socket closed, target stream still valid. */ PUBLIC int HTCopy ARGS4( HTParentAnchor *, anchor, @@ -516,8 +592,7 @@ PUBLIC int HTCopy ARGS4( HTStream*, sink) { HTStreamClass targetClass; - char line[256]; - int bytes = 0; + int bytes; int rv = 0; /* Push the data down the stream @@ -528,6 +603,7 @@ PUBLIC int HTCopy ARGS4( ** ** This operation could be put into a main event loop */ + HTReadProgress(bytes = 0, 0); for (;;) { int status; @@ -539,7 +615,7 @@ PUBLIC int HTCopy ARGS4( } if (HTCheckForInterrupt()) { - _HTProgress ("Data transfer interrupted."); + _HTProgress (TRANSFER_INTERRUPTED); (*targetClass._abort)(sink, NULL); if (bytes) rv = HT_INTERRUPTED; @@ -554,7 +630,7 @@ PUBLIC int HTCopy ARGS4( if (status == 0) { break; } else if (status == HT_INTERRUPTED) { - _HTProgress ("Data transfer interrupted."); + _HTProgress (TRANSFER_INTERRUPTED); (*targetClass._abort)(sink, NULL); if (bytes) rv = HT_INTERRUPTED; @@ -565,7 +641,7 @@ PUBLIC int HTCopy ARGS4( SOCKET_ERRNO == ECONNRESET || SOCKET_ERRNO == EPIPE) { /* - * Arrrrgh, HTTP 0/1 compability problem, maybe. + * Arrrrgh, HTTP 0/1 compatibility problem, maybe. */ if (bytes <= 0) { /* @@ -575,16 +651,51 @@ PUBLIC int HTCopy ARGS4( rv = -2; goto finished; } else { +#ifdef UNIX + /* + * Treat what we've received already as the complete + * transmission, but not without giving the user + * an alert. I don't know about all the different + * TCP stacks for VMS etc., so this is currently + * only for UNIX. - kw + */ + HTInetStatus("NETREAD"); + HTAlert("Unexpected server disconnect."); + CTRACE(tfp, + "HTCopy: Unexpected server disconnect. Treating as completed.\n"); + status = 0; + break; +#else /* !UNIX */ /* * Treat what we've gotten already * as the complete transmission. - FM */ - if (TRACE) - fprintf(stderr, - "HTCopy: Unexpected server disconnect. Treating as completed.\n"); + CTRACE(tfp, + "HTCopy: Unexpected server disconnect. Treating as completed.\n"); status = 0; break; +#endif /* UNIX */ } +#ifdef UNIX + } else { /* status < 0 and other errno */ + /* + * Treat what we've received already as the complete + * transmission, but not without giving the user + * an alert. I don't know about all the different + * TCP stacks for VMS etc., so this is currently + * only for UNIX. - kw + */ + HTInetStatus("NETREAD"); + HTAlert("Unexpected read error."); + if (bytes) { + (void)NETCLOSE(file_number); + rv = HT_LOADED; + } else { + (*targetClass._abort)(sink, NULL); + rv = -1; + } + goto finished; +#endif } break; } @@ -599,22 +710,18 @@ PUBLIC int HTCopy ARGS4( #endif /* NOT_ASCII */ (*targetClass.put_block)(sink, input_buffer, status); - bytes += status; - if (anchor && anchor->content_length > 0) - sprintf(line, "Read %d of %d bytes of data.", - bytes, anchor->content_length); - else - sprintf(line, "Read %d bytes of data.", bytes); - HTProgress(line); + HTReadProgress(bytes, anchor ? anchor->content_length : 0); + HTDisplayPartial(); } /* next bufferload */ - _HTProgress("Data transfer complete"); + _HTProgress(TRANSFER_COMPLETE); (void)NETCLOSE(file_number); rv = HT_LOADED; finished: + HTFinishDisplayPartial(); return(rv); } @@ -625,14 +732,25 @@ finished: ** graphic (or other) objects described by the file. ** ** +** State of file and target stream on entry: +** FILE* (fp) assumed open, +** target (sink) assumed valid. +** +** Return values: +** HT_INTERRUPTED Interruption after some data read. +** HT_PARTIAL_CONTENT Error after some data read. +** -1 Error before any data read. +** HT_LOADED Normal end of file indication on reading. +** +** State of file and target stream on return: +** always fp still open, target stream still valid. */ PUBLIC int HTFileCopy ARGS2( - FILE *, fp, + FILE *, fp, HTStream*, sink) { HTStreamClass targetClass; - char line[256]; - int status, bytes = 0, nreads = 0, nprogr = 0; + int status, bytes; int rv = HT_OK; /* Push the data down the stream @@ -641,17 +759,15 @@ PUBLIC int HTFileCopy ARGS2( /* Push binary from socket down sink */ + HTReadProgress(bytes = 0, 0); for (;;) { status = fread(input_buffer, 1, INPUT_BUFFER_SIZE, fp); - nreads++; if (status == 0) { /* EOF or error */ if (ferror(fp) == 0) { rv = HT_LOADED; break; } - if (TRACE) - fprintf(stderr, - "HTFormat: Read error, read returns %d\n", + CTRACE(tfp, "HTFormat: Read error, read returns %d\n", ferror(fp)); if (bytes) { rv = HT_PARTIAL_CONTENT; @@ -660,47 +776,85 @@ PUBLIC int HTFileCopy ARGS2( } break; } - (*targetClass.put_block)(sink, input_buffer, status); + (*targetClass.put_block)(sink, input_buffer, status); bytes += status; - if (nreads >= 100) { - /* - ** Show progress messages for local files, and check for - ** user interruption. Start doing so only after a certain - ** number of reads have been done, and don't update it on - ** every read (normally reading in a local file should be - ** speedy). - KW - */ - if (nprogr == 0) { - if (bytes < 1024000) { - sprintf(line, "Read %d bytes of data.", bytes); - } else { - sprintf(line, "Read %d KB of data. %s", - bytes/1024, - "(Press 'z' if you want to abort loading.)"); - } - HTProgress(line); - if (HTCheckForInterrupt()) { - _HTProgress ("Data transfer interrupted."); - if (bytes) { - rv = HT_INTERRUPTED; - } else { - rv = -1; - } - break; - } - nprogr++; - } else if (nprogr == 25) { - nprogr = 0; + HTReadProgress(bytes, 0); + HTDisplayPartial(); + + if (HTCheckForInterrupt()) { + _HTProgress (TRANSFER_INTERRUPTED); + if (bytes) { + rv = HT_INTERRUPTED; } else { - nprogr++; + rv = -1; } + break; } } /* next bufferload */ + HTFinishDisplayPartial(); return rv; } +#ifdef SOURCE_CACHE +/* Push data from an HTChunk down a stream +** --------------------------------------- +** +** This routine is responsible for creating and PRESENTING any +** graphic (or other) objects described by the file. +** +** State of memory and target stream on entry: +** HTChunk* (chunk) and target (sink) assumed valid. +** +** Return values: +** HT_LOADED All data sent. +** HT_INTERRUPTED Interruption after some data read. +** +** State of memory and target stream on return: +** always chunk unchanged, target stream still valid. +*/ +PUBLIC int HTMemCopy ARGS2( + HTChunk *, chunk, + HTStream *, sink) +{ + HTStreamClass targetClass = *(sink->isa); + int bytes = 0; + CONST char *data = chunk->data; + int rv = HT_OK; + + HTReadProgress(0, 0); + for (;;) { + /* Push the data down the stream a piece at a time, in case we're + ** running a large document on a slow machine. + */ + int n = INPUT_BUFFER_SIZE; + if (n > chunk->size - bytes) + n = chunk->size - bytes; + if (n == 0) + break; + (*targetClass.put_block)(sink, data, n); + bytes += n; + data += n; + HTReadProgress(bytes, 0); + HTDisplayPartial(); + + if (HTCheckForInterrupt()) { + _HTProgress (TRANSFER_INTERRUPTED); + if (bytes) { + rv = HT_INTERRUPTED; + } else { + rv = -1; + } + break; + } + } + + HTFinishDisplayPartial(); + return rv; +} +#endif + #ifdef USE_ZLIB /* Push data from a gzip file pointer down a stream ** ------------------------------------- @@ -709,14 +863,25 @@ PUBLIC int HTFileCopy ARGS2( ** graphic (or other) objects described by the file. ** ** +** State of file and target stream on entry: +** gzFile (gzfp) assumed open (should have gzipped content), +** target (sink) assumed valid. +** +** Return values: +** HT_INTERRUPTED Interruption after some data read. +** HT_PARTIAL_CONTENT Error after some data read. +** -1 Error before any data read. +** HT_LOADED Normal end of file indication on reading. +** +** State of file and target stream on return: +** always gzfp still open, target stream still valid. */ PRIVATE int HTGzFileCopy ARGS2( - gzFile, gzfp, + gzFile, gzfp, HTStream*, sink) { HTStreamClass targetClass; - char line[256]; - int status, bytes = 0, nreads = 0, nprogr = 0; + int status, bytes; int gzerrnum; int rv = HT_OK; @@ -724,23 +889,21 @@ PRIVATE int HTGzFileCopy ARGS2( */ targetClass = *(sink->isa); /* Copy pointers to procedures */ - /* read and inflate gzipped file, and push binary down sink + /* read and inflate gzip'd file, and push binary down sink */ + HTReadProgress(bytes = 0, 0); for (;;) { status = gzread(gzfp, input_buffer, INPUT_BUFFER_SIZE); - nreads++; if (status <= 0) { /* EOF or error */ if (status == 0) { rv = HT_LOADED; break; } - if (TRACE) { - fprintf(stderr, - "HTGzFileCopy: Read error, gzread returns %d\n", + CTRACE(tfp, "HTGzFileCopy: Read error, gzread returns %d\n", status); - fprintf(stderr, - "gzerror : %s\n", + CTRACE(tfp, "gzerror : %s\n", gzerror(gzfp, &gzerrnum)); + if (TRACE) { if (gzerrnum == Z_ERRNO) perror("gzerror "); } @@ -751,45 +914,24 @@ PRIVATE int HTGzFileCopy ARGS2( } break; } - (*targetClass.put_block)(sink, input_buffer, status); + (*targetClass.put_block)(sink, input_buffer, status); bytes += status; - if (nreads >= 100) { - /* - ** Show progress messages for local files, and check for - ** user interruption. Start doing so only after a certain - ** number of reads have been done, and don't update it on - ** every read (normally reading in a local file should be - ** speedy). - KW - */ - if (nprogr == 0) { - if (bytes < 1024000) { - sprintf(line, - "Read %d uncompressed bytes of data.", bytes); - } else { - sprintf(line, "Read %d uncompressed KB of data. %s", - bytes/1024, - "(Press 'z' to abort.)"); - } - HTProgress(line); - if (HTCheckForInterrupt()) { - _HTProgress ("Data transfer interrupted."); - if (bytes) { - rv = HT_INTERRUPTED; - } else { - rv = -1; - } - break; - } - nprogr++; - } else if (nprogr == 25) { - nprogr = 0; + HTReadProgress(bytes, -1); + HTDisplayPartial(); + + if (HTCheckForInterrupt()) { + _HTProgress (TRANSFER_INTERRUPTED); + if (bytes) { + rv = HT_INTERRUPTED; } else { - nprogr++; + rv = -1; } + break; } } /* next bufferload */ + HTFinishDisplayPartial(); return rv; } #endif /* USE_ZLIB */ @@ -840,6 +982,30 @@ PUBLIC void HTCopyNoCR ARGS3( ** CRLF at the end of lines which need to be stripped to LF for unix ** when the format is textual. ** +** State of socket and target stream on entry: +** socket (file_number) assumed open, +** target (sink) usually NULL (will call stream stack). +** +** Return values: +** HT_INTERRUPTED Interruption or error after some data received. +** -501 Stream stack failed (cannot present or convert). +** -2 Unexpected disconnect before any data received. +** -1 Stream stack failed (cannot present or convert), or +** Interruption or error before any data received, or +** (UNIX) other read error before any data received, or +** download cancelled. +** HT_LOADED Normal close of socket (end of file indication +** received), or +** unexpected disconnect after some data received, or +** other read error after some data received, or +** (not UNIX) other read error before any data received. +** +** State of socket and target stream on return depends on return value: +** HT_INTERRUPTED socket still open, target aborted. +** -501 socket still open, target stream NULL. +** -2 socket still open, target freed. +** -1 socket still open, target stream aborted or NULL. +** otherwise socket closed, target stream freed. */ PUBLIC int HTParseSocket ARGS5( HTFormat, rep_in, @@ -855,27 +1021,27 @@ PUBLIC int HTParseSocket ARGS5( stream = HTStreamStack(rep_in, format_out, sink, anchor); if (!stream) { - char buffer[1024]; /* @@@@@@@@ */ + char *buffer = 0; if (LYCancelDownload) { LYCancelDownload = FALSE; return -1; } - sprintf(buffer, "Sorry, can't convert from %s to %s.", + HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - if (TRACE) - fprintf(stderr, "HTFormat: %s\n", buffer); - return HTLoadError(sink, 501, buffer); /* returns -501 */ + CTRACE(tfp, "HTFormat: %s\n", buffer); + rv = HTLoadError(sink, 501, buffer); /* returns -501 */ + FREE(buffer); + } else { + /* + ** Push the data, don't worry about CRLF we can strip them later. + */ + targetClass = *(stream->isa); /* Copy pointers to procedures */ + rv = HTCopy(anchor, file_number, NULL, stream); + if (rv != -1 && rv != HT_INTERRUPTED) + (*targetClass._free)(stream); } - - /* - ** Push the data, don't worry about CRLF we can strip them later. - */ - targetClass = *(stream->isa); /* Copy pointers to procedures */ - rv = HTCopy(anchor, file_number, NULL, stream); - if (rv != -1 && rv != HT_INTERRUPTED) - (*targetClass._free)(stream); - - return rv; /* full: HT_LOADED; partial: HT_INTERRUPTED; no bytes: -1 */ + return rv; + /* Originally: full: HT_LOADED; partial: HT_INTERRUPTED; no bytes: -1 */ } /* Parse a file given format and file pointer @@ -887,12 +1053,25 @@ PUBLIC int HTParseSocket ARGS5( ** CRLF at the end of lines which need to be stripped to \n for unix ** when the format is textual. ** +** State of file and target stream on entry: +** FILE* (fp) assumed open, +** target (sink) usually NULL (will call stream stack). +** +** Return values: +** -501 Stream stack failed (cannot present or convert). +** -1 Download cancelled. +** HT_NO_DATA Error before any data read. +** HT_PARTIAL_CONTENT Interruption or error after some data read. +** HT_LOADED Normal end of file indication on reading. +** +** State of file and target stream on return: +** always fp still open; target freed, aborted, or NULL. */ PUBLIC int HTParseFile ARGS5( HTFormat, rep_in, HTFormat, format_out, HTParentAnchor *, anchor, - FILE *, fp, + FILE *, fp, HTStream*, sink) { HTStream * stream; @@ -904,16 +1083,17 @@ PUBLIC int HTParseFile ARGS5( sink , anchor); if (!stream) { - char buffer[1024]; /* @@@@@@@@ */ + char *buffer = 0; if (LYCancelDownload) { LYCancelDownload = FALSE; return -1; } - sprintf(buffer, "Sorry, can't convert from %s to %s.", + HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - if (TRACE) - fprintf(stderr, "HTFormat(in HTParseFile): %s\n", buffer); - return HTLoadError(sink, 501, buffer); + CTRACE(tfp, "HTFormat(in HTParseFile): %s\n", buffer); + rv = HTLoadError(sink, 501, buffer); + FREE(buffer); + return rv; } /* Push the data down the stream @@ -938,9 +1118,57 @@ PUBLIC int HTParseFile ARGS5( return HT_LOADED; } +#ifdef SOURCE_CACHE +/* Parse a document in memory given format and memory block pointer +** +** This routine is responsible for creating and PRESENTING any +** graphic (or other) objects described by the file. +** +** State of memory and target stream on entry: +** HTChunk* (chunk) assumed valid, +** target (sink) usually NULL (will call stream stack). +** +** Return values: +** -501 Stream stack failed (cannot present or convert). +** HT_LOADED All data sent. +** +** Stat of memory and target stream on return: +** always chunk unchanged; target freed, aborted, or NULL. +*/ +PUBLIC int HTParseMem ARGS5( + HTFormat, rep_in, + HTFormat, format_out, + HTParentAnchor *, anchor, + HTChunk *, chunk, + HTStream *, sink) +{ + HTStream * stream; + HTStreamClass targetClass; + int rv; + + stream = HTStreamStack(rep_in, format_out, sink, anchor); + if (!stream) { + char *buffer = 0; + HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, + HTAtom_name(rep_in), HTAtom_name(format_out)); + CTRACE(tfp, "HTFormat(in HTParseMem): %s\n", buffer); + rv = HTLoadError(sink, 501, buffer); + FREE(buffer); + return rv; + } + + /* Push the data down the stream + */ + targetClass = *(stream->isa); + rv = HTMemCopy(chunk, stream); + (*targetClass._free)(stream); + return HT_LOADED; +} +#endif + #ifdef USE_ZLIB PRIVATE int HTCloseGzFile ARGS1( - gzFile, gzfp) + gzFile, gzfp) { int gzres; if (gzfp == NULL) @@ -950,17 +1178,33 @@ PRIVATE int HTCloseGzFile ARGS1( if (gzres == Z_ERRNO) { perror("gzclose "); } else if (gzres != Z_OK) { - fprintf(stderr, "gzclose : error number %d\n", gzres); + CTRACE(tfp, "gzclose : error number %d\n", gzres); } } return(gzres); } +/* HTParseGzFile +** +** State of file and target stream on entry: +** gzFile (gzfp) assumed open, +** target (sink) usually NULL (will call stream stack). +** +** Return values: +** -501 Stream stack failed (cannot present or convert). +** -1 Download cancelled. +** HT_NO_DATA Error before any data read. +** HT_PARTIAL_CONTENT Interruption or error after some data read. +** HT_LOADED Normal end of file indication on reading. +** +** State of file and target stream on return: +** always gzfp closed; target freed, aborted, or NULL. +*/ PUBLIC int HTParseGzFile ARGS5( HTFormat, rep_in, HTFormat, format_out, HTParentAnchor *, anchor, - gzFile, gzfp, + gzFile, gzfp, HTStream*, sink) { HTStream * stream; @@ -972,18 +1216,18 @@ PUBLIC int HTParseGzFile ARGS5( sink , anchor); if (!stream) { - char buffer[1024]; /* @@@@@@@@ */ - extern char LYCancelDownload; + char *buffer = 0; HTCloseGzFile(gzfp); if (LYCancelDownload) { LYCancelDownload = FALSE; return -1; } - sprintf(buffer, "Sorry, can't convert from %s to %s.", + HTSprintf0(&buffer, CANNOT_CONVERT_I_TO_O, HTAtom_name(rep_in), HTAtom_name(format_out)); - if (TRACE) - fprintf(stderr, "HTFormat(in HTParseGzFile): %s\n", buffer); - return HTLoadError(sink, 501, buffer); + CTRACE(tfp, "HTFormat(in HTParseGzFile): %s\n", buffer); + rv = HTLoadError(sink, 501, buffer); + FREE(buffer); + return rv; } /* Push the data down the stream |
