summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c')
-rw-r--r--gnu/usr.bin/lynx/WWW/Library/Implementation/HTFormat.c630
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