📄 htformat.c
字号:
p = (HTPresentation *)HTList_objectAt(HTPresentations, i); s = HTAtom_name(p->rep); if (p->rep_out == WWW_PRESENT) { if (p->rep != WWW_SOURCE && strcasecomp(s, "www/mime") && strcasecomp(s, "www/compressed") && p->quality <= 1.0 && p->quality >= 0.0) { for (j = 0, matched = FALSE; j < i; j++) { q = (HTPresentation *)HTList_objectAt(HTPresentations, j); t = HTAtom_name(q->rep); if (!strcasecomp(s, t)) { matched = TRUE; break; } if ((x = strchr(s, '/')) != 0 && (y = strchr(t, '/')) != 0) { int len1 = x++ - s; int len2 = y++ - t; int lens = (len1 > len2) ? len1 : len2; if ((*t == '*' || !strncasecomp(s, t, lens)) && (*y == '*' || !strcasecomp(x, y))) { matched = TRUE; break; } } } if (!matched) p->get_accept = TRUE; } } }}/* Find the cost of a filter stack** -------------------------------**** Must return the cost of the same stack which StreamStack would set up.**** On entry,** length The size of the data to be converted*/PUBLIC float HTStackValue ARGS4( HTFormat, rep_in, HTFormat, rep_out, float, initial_value, long int, length){ 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 */ ) { NumOfLines_partial = HText_getNumOfLines(); LYMainLoop_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 /* * 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;#ifdef _WINDOWS /* 1997/11/11 (Tue) 15:18:16 */ long file_length; extern int bytes_already_read; file_length = anchor->content_length;#endif /* 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 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -