summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/HTFWriter.c165
-rw-r--r--src/LYCurses.c4
-rw-r--r--src/LYIcon.rc10
3 files changed, 163 insertions, 16 deletions
diff --git a/src/HTFWriter.c b/src/HTFWriter.c
index b07aa92..6e961e2 100644
--- a/src/HTFWriter.c
+++ b/src/HTFWriter.c
@@ -1,5 +1,5 @@
/*
- * $LynxId: HTFWriter.c,v 1.126 2024/04/11 20:21:33 tom Exp $
+ * $LynxId: HTFWriter.c,v 1.129 2024/05/27 17:02:24 tom Exp $
*
* FILE WRITER HTFWrite.h
* ===========
@@ -45,6 +45,10 @@
#include <LYCookie.h>
#endif
+#ifdef USE_BROTLI
+#include <brotli/decode.h>
+#endif
+
/* contains the name of the temp file which is being downloaded into */
char *WWW_Download_File = NULL;
BOOLEAN LYCancelDownload = FALSE; /* exported to HTFormat.c in libWWW */
@@ -186,15 +190,155 @@ static void decompress_gzip(HTStream *me)
#define FMT "%s %s"
const char *program;
- if (LYCopyFile(in_name, copied) == 0) {
+ if ((program = HTGetProgramPath(ppUNCOMPRESS)) == NULL) {
+ HTAlert(ERROR_UNCOMPRESSING_TEMP);
+ } else if (LYCopyFile(in_name, copied) == 0) {
char expanded[LY_MAXPATH];
char *command = NULL;
- if ((program = HTGetProgramPath(ppUNCOMPRESS)) != NULL) {
- HTAddParam(&command, FMT, 1, program);
- HTAddParam(&command, FMT, 2, copied);
- HTEndParam(&command, FMT, 2);
+ HTAddParam(&command, FMT, 1, program);
+ HTAddParam(&command, FMT, 2, copied);
+ HTEndParam(&command, FMT, 2);
+ if (LYSystem(command) == 0) {
+ struct stat stat_buf;
+
+ strcpy(expanded, copied);
+ *strrchr(expanded, '.') = '\0';
+ if (LYRenameFile(expanded, in_name) != 0) {
+ CTRACE((tfp, "rename failed %s to %s\n", expanded, in_name));
+ } else if (stat(in_name, &stat_buf) != 0) {
+ CTRACE((tfp, "stat failed for %s\n", in_name));
+ } else {
+ me->anchor->actual_length = stat_buf.st_size;
+ }
+ } else {
+ CTRACE((tfp, "command failed: %s\n", command));
}
+ free(command);
+ (void) LYRemoveTemp(copied);
+ }
+#undef FMT
+#endif
+ }
+}
+
+static void decompress_br(HTStream *me)
+{
+#undef THIS_FUNC
+#define THIS_FUNC "decompress_br\n"
+ char *in_name = me->anchor->FileCache;
+ char copied[LY_MAXPATH];
+ FILE *fp = LYOpenTemp(copied, ".br", BIN_W);
+
+ if (fp != 0) {
+#ifdef USE_BROTLI
+#define INPUT_BUFFER_SIZE BUFSIZ
+ char *brotli_buffer = NULL;
+ char *normal_buffer = NULL;
+ size_t brotli_size;
+ size_t brotli_limit = 0;
+ size_t brotli_offset;
+ size_t normal_size;
+ size_t normal_limit = 0;
+ BrotliDecoderResult status2 = BROTLI_DECODER_RESULT_ERROR;
+ int status;
+ off_t bytes = 0;
+ FILE *ifp = fopen(in_name, BIN_R);
+
+ if (ifp != NULL) {
+ CTRACE((tfp, "reading '%s'\n", in_name));
+ for (;;) {
+ size_t input_chunk = INPUT_BUFFER_SIZE;
+
+ brotli_offset = brotli_limit;
+ brotli_limit += input_chunk;
+ brotli_buffer = realloc(brotli_buffer, brotli_limit);
+ if (brotli_buffer == NULL)
+ outofmem(__FILE__, THIS_FUNC);
+ status = (int) fread(brotli_buffer + brotli_offset,
+ sizeof(char),
+ input_chunk,
+ ifp);
+
+ if (status <= 0) { /* EOF or error */
+ if (status == 0) {
+ break;
+ }
+ CTRACE((tfp, THIS_FUNC ": Read error, fread returns %d\n", status));
+ break;
+ }
+ bytes += status;
+ }
+ fclose(ifp);
+
+ CTRACE((tfp, "decompressing '%s'\n", in_name));
+ /*
+ * next, unless we encountered an error (and have no data), try
+ * decompressing with increasing output buffer sizes until the brotli
+ * library succeeds.
+ */
+ if (bytes > 0) {
+ do {
+ if (normal_limit == 0)
+ normal_limit = (10 * brotli_limit) + INPUT_BUFFER_SIZE;
+ else
+ normal_limit *= 2;
+ normal_buffer = realloc(normal_buffer, normal_limit);
+ if (normal_buffer == NULL)
+ outofmem(__FILE__, THIS_FUNC);
+ brotli_size = (size_t) bytes;
+ normal_size = normal_limit;
+ status2 = BrotliDecoderDecompress(brotli_size,
+ (uint8_t *) brotli_buffer,
+ &normal_size,
+ (uint8_t *) normal_buffer);
+ /*
+ * brotli library should return
+ * BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT,
+ * but actually returns
+ * BROTLI_DECODER_RESULT_ERROR
+ *
+ * Accommodate possible improvements...
+ */
+ } while (status2 != BROTLI_DECODER_RESULT_SUCCESS);
+ }
+
+ /*
+ * finally, pump that data into the output stream.
+ */
+ if (status2 == BROTLI_DECODER_RESULT_SUCCESS) {
+ CTRACE((tfp, THIS_FUNC ": decompressed %ld -> %ld (1:%.1f)\n",
+ brotli_size, normal_size,
+ (double) normal_size / (double) brotli_size));
+ fwrite(normal_buffer, sizeof(char), normal_size, fp);
+ }
+ free(brotli_buffer);
+ free(normal_buffer);
+
+ LYCloseTempFP(fp);
+
+ CTRACE((tfp, "...decompress %" PRI_off_t " to %lu\n",
+ CAST_off_t (me->anchor->actual_length),
+ (unsigned long)normal_size));
+ if (status2 == BROTLI_DECODER_RESULT_SUCCESS) {
+ if (LYRenameFile(copied, in_name) == 0)
+ me->anchor->actual_length = (off_t) normal_size;
+ }
+ (void) LYRemoveTemp(copied);
+ }
+#else
+#define FMT "%s -j -d %s"
+ const char *program;
+
+ if ((program = HTGetProgramPath(ppBROTLI)) == NULL) {
+ HTAlert(ERROR_UNCOMPRESSING_TEMP);
+ } else if (LYCopyFile(in_name, copied) == 0) {
+ char expanded[LY_MAXPATH];
+ char *command = NULL;
+
+ HTAddParam(&command, FMT, 1, program);
+ HTAddParam(&command, FMT, 2, copied);
+ HTEndParam(&command, FMT, 2);
if (LYSystem(command) == 0) {
struct stat stat_buf;
@@ -252,12 +396,17 @@ static void HTFWriter_free(HTStream *me)
*/
if (me->anchor->FileCache != NULL
&& me->anchor->no_content_encoding == FALSE
- && me->input_format == HTAtom_for("application/x-gzip")
+ && IsCompressionFormat(me->input_format, cftGzip)
&& !strcmp(me->anchor->content_encoding, "gzip")) {
decompress_gzip(me);
+ } else if (me->anchor->FileCache != NULL
+ && me->anchor->no_content_encoding == FALSE
+ && IsCompressionFormat(me->input_format, cftBrotli)
+ && !strcmp(me->anchor->content_encoding, "br")) {
+ decompress_br(me);
}
#ifdef VMS
- if (0 == strcmp(me->end_command, "SaveVMSBinaryFile")) {
+ else if (0 == strcmp(me->end_command, "SaveVMSBinaryFile")) {
/*
* It's a binary file saved to disk on VMS, which
* we want to convert to fixed records format. - FM
diff --git a/src/LYCurses.c b/src/LYCurses.c
index d1ad337..a7cf9ec 100644
--- a/src/LYCurses.c
+++ b/src/LYCurses.c
@@ -1,4 +1,4 @@
-/* $LynxId: LYCurses.c,v 1.207 2024/01/09 00:30:44 tom Exp $ */
+/* $LynxId: LYCurses.c,v 1.209 2024/04/16 21:43:44 tom Exp $ */
#include <HTUtils.h>
#include <HTAlert.h>
@@ -931,14 +931,12 @@ static void delete_screen(SCREEN * screen)
static SCREEN *LYscreen = NULL;
-#if defined(USE_DEFAULT_COLORS)
static void delete_screen(SCREEN * screen)
{
delete_fake_win();
delete_subwindow();
delscreen(screen);
}
-#endif
#define LYDELSCR() { \
CheckScreenSize(); \
diff --git a/src/LYIcon.rc b/src/LYIcon.rc
index 3076d34..6301589 100644
--- a/src/LYIcon.rc
+++ b/src/LYIcon.rc
@@ -1,12 +1,12 @@
-// $LynxId: LYIcon.rc,v 1.66 2024/04/15 20:53:51 tom Exp $
+// $LynxId: LYIcon.rc,v 1.72 2024/05/31 22:09:16 tom Exp $
#include <windows.h>
100 ICON "../samples/lynx.ico"
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 2,9,1,0
-PRODUCTVERSION 2,9,1,0
+FILEVERSION 2,9,2,0
+PRODUCTVERSION 2,9,2,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
@@ -19,12 +19,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "https://invisible-island.net/lynx"
VALUE "FileDescription", "Lynx - web browser"
- VALUE "FileVersion", "2.9.1.0"
+ VALUE "FileVersion", "2.9.2.0"
VALUE "InternalName", "Lynx"
VALUE "LegalCopyright", "©1997-2024 Thomas E. Dickey"
VALUE "OriginalFilename", "lynx.exe"
VALUE "ProductName", "Lynx - web browser"
- VALUE "ProductVersion", "2.9.1.0"
+ VALUE "ProductVersion", "2.9.2.0"
END
END
BLOCK "VarFileInfo"