📄 htformat.c
字号:
HTAtom * wildcard = WWW_WILDCARD_REP_OUT; 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) return 0.0; /* don't do anymore do it in the Lynx code at startup LJM */ /* if (!HTPresentations) HTFormatInit(); */ /* set up the list */ { int n = HTList_count(HTPresentations); int i; HTPresentation * pres; for (i = 0; i < n; i++) { pres = (HTPresentation *)HTList_objectAt(HTPresentations, i); if (pres->rep == rep_in && (pres->rep_out == rep_out || pres->rep_out == wildcard)) { float value = initial_value * pres->quality; if (HTMaxSecs != 0.0) value = value - (length*pres->secs_per_byte + pres->secs) /HTMaxSecs; return value; } } } return (float) -1e30; /* Really bad */}/* 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 complete lines received ** NumOfLines_partial = number of lines at the moment of last repaint. ** (we update NumOfLines_partial only when we repaint the display.) ** ** display_partial could only be enabled in HText_new() ** so a new HTMainText object available - all HText_ functions use it, ** lines counter HText_getNumOfLines() in particular. ** ** 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: */ int Newline_partial = LYGetNewline(); if (((Newline_partial + display_lines) - 1 > NumOfLines_partial) /* current page not complete... */ && (partial_threshold > 0 ? ((Newline_partial + partial_threshold) -1 <= HText_getNumOfLines()) : ((Newline_partial + display_lines) - 1 <= 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 */ ) { if (LYMainLoop_pageDisplay(Newline_partial)) NumOfLines_partial = HText_getNumOfLines(); } }#else /* nothing */#endif /* DISP_PARTIAL */}/* Put this as early as possible, OK just after HTDisplayPartial() */PUBLIC void HTFinishDisplayPartial NOARGS{#ifdef DISP_PARTIAL /* * End of incremental rendering stage here. */ display_partial = FALSE;#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, 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, int, file_number, void*, handle GCC_UNUSED, HTStream*, sink){ HTStreamClass targetClass; BOOL suppress_readprogress = NO; int bytes; int rv = 0; /* Push the data down the stream */ targetClass = *(sink->isa); /* Copy pointers to procedures */ /* Push binary from socket down sink ** ** This operation could be put into a main event loop */ HTReadProgress(bytes = 0, 0); for (;;) { int status; if (LYCancelDownload) { LYCancelDownload = FALSE; (*targetClass._abort)(sink, NULL); rv = -1; goto finished; } if (HTCheckForInterrupt()) { _HTProgress (TRANSFER_INTERRUPTED); (*targetClass._abort)(sink, NULL); if (bytes) rv = HT_INTERRUPTED; else rv = -1; goto finished; }#ifdef USE_SSL if (handle) status = SSL_read((SSL *)handle, input_buffer, INPUT_BUFFER_SIZE); else status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE);#else status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE);#endif /* USE_SSL */ if (status <= 0) { if (status == 0) { break; } else if (status == HT_INTERRUPTED) { _HTProgress (TRANSFER_INTERRUPTED); (*targetClass._abort)(sink, NULL); if (bytes) rv = HT_INTERRUPTED; else rv = -1; goto finished; } else if (SOCKET_ERRNO == ENOTCONN ||#ifdef _WINDOWS /* 1997/11/10 (Mon) 16:57:18 */ SOCKET_ERRNO == ETIMEDOUT ||#endif SOCKET_ERRNO == ECONNRESET || SOCKET_ERRNO == EPIPE) { /* * Arrrrgh, HTTP 0/1 compatibility problem, maybe. */ if (bytes <= 0) { /* * Don't have any data, so let the calling * function decide what to do about it. - FM */ 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 */ 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; } /* * Suppress ReadProgress messages when collecting a redirection * message, at least initially (unless/until anchor->content_type * gets changed, probably by the MIME message parser). That way * messages put up by the HTTP module or elsewhere can linger in * the statusline for a while. - kw */ suppress_readprogress = (anchor && anchor->content_type && !strcmp(anchor->content_type, "message/x-http-redirection"));#ifdef NOT_ASCII { char * p; for (p = input_buffer; p < input_buffer+status; p++) { *p = FROMASCII(*p); } }#endif /* NOT_ASCII */ (*targetClass.put_block)(sink, input_buffer, status); bytes += status; if (!suppress_readprogress) HTReadProgress(bytes, anchor ? anchor->content_length : 0); HTDisplayPartial(); } /* next bufferload */ _HTProgress(TRANSFER_COMPLETE); (void)NETCLOSE(file_number); rv = HT_LOADED;finished: HTFinishDisplayPartial(); return(rv);}/* Push data from a file pointer down a stream** -------------------------------------**** This routine is responsible for creating and PRESENTING any** 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, HTStream*, sink){ HTStreamClass targetClass; int status, bytes; int rv = HT_OK; /* Push the data down the stream */ targetClass = *(sink->isa); /* Copy pointers to procedures */ /* Push binary from socket down sink */ HTReadProgress(bytes = 0, 0); for (;;) { status = fread(input_buffer, 1, INPUT_BUFFER_SIZE, fp); if (status == 0) { /* EOF or error */ if (ferror(fp) == 0) { rv = HT_LOADED; break; } CTRACE((tfp, "HTFormat: Read error, read returns %d\n", ferror(fp))); if (bytes) { rv = HT_PARTIAL_CONTENT; } else { rv = -1; } break; } (*targetClass.put_block)(sink, input_buffer, status); bytes += status; HTReadProgress(bytes, 0); /* Suppress last screen update in partial mode - a regular update * under control of mainloop() should follow anyway. - kw */#ifdef DISP_PARTIAL if (display_partial && bytes != HTMainAnchor->content_length) HTDisplayPartial();#endif if (HTCheckForInterrupt()) { _HTProgress (TRANSFER_INTERRUPTED); if (bytes) { rv = HT_INTERRUPTED; } else { rv = -1; } break; } } /* next bufferload */ HTFinishDisplayPartial(); return rv;}#ifdef USE_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; int bytes = 0; CONST char *data = chunk->data; int rv = HT_OK; targetClass = *(sink->isa); 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** -------------------------------------**** This routine is responsible for creating and PRESENTING any** 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, HTStream*, sink){ HTStreamClass targetClass; int status, bytes; int gzerrnum; int rv = HT_OK; /* Push the data down the stream */ targetClass = *(sink->isa); /* Copy pointers to procedures */ /* read and inflate gzip'd file, and push binary down sink */ HTReadProgress(bytes = 0, 0); for (;;) { status = gzread(gzfp, input_buffer, INPUT_BUFFER_SIZE); if (status <= 0) { /* EOF or error */ if (status == 0) { rv = HT_LOADED; break; } CTRACE((tfp, "HTGzFileCopy: Read error, gzread returns %d\n", status)); CTRACE((tfp, "gzerror : %s\n", gzerror(gzfp, &gzerrnum))); if (TRACE) { if (gzerrnum == Z_ERRNO) perror("gzerror "); } if (bytes) { rv = HT_PARTIAL_CONTENT; } else { rv = -1; } break; } (*targetClass.put_block)(sink, input_buffer, status); bytes += status; HTReadProgress(bytes, -1); HTDisplayPartial(); if (HTCheckForInterrupt()) { _HTProgress (TRANSFER_INTERRUPTED); if (bytes) { rv = HT_INTERRUPTED; } else { rv = -1; } break; } } /* next bufferload */ HTFinishDisplayPartial(); return rv;}#endif /* USE_ZLIB */#ifdef USE_BZLIB/* Push data from a bzip file pointer down a stream** -------------------------------------**** This routine is responsible for creating and PRESENTING any** graphic (or other) objects described by the file.****** State of file and target stream on entry:** BZFILE (bzfp) assumed open (should have bzipped 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 bzfp still open, target stream still valid.*/PRIVATE int HTBzFileCopy ARGS2( BZFILE *, bzfp, HTStream*, sink){ HTStreamClass targetClass; int status, bytes; int bzerrnum; int rv = HT_OK; /* Push the data down the stream */ targetClass = *(sink->isa); /* Copy pointers to procedures */ /* read and inflate bzip'd file, and push binary down sink */ HTReadProgress(bytes = 0, 0); for (;;) { status = BZ2_bzread(bzfp, input_buffer, INPUT_BUFFER_SIZE); if (status <= 0) { /* EOF or error */ if (status == 0) { rv = HT_LOADED; break; } CTRACE((tfp, "HTBzFileCopy: Read error, bzread returns %d\n", status)); CTRACE((tfp, "bzerror : %s\n", BZ2_bzerror(bzfp, &bzerrnum))); if (bytes) { rv = HT_PARTIAL_CONTENT; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -