From acc4233b4155f35d2bdb38547f60f1658e3ee2da Mon Sep 17 00:00:00 2001 From: kichik Date: Wed, 27 Jun 2007 11:09:40 +0000 Subject: [PATCH] applied patch #1723131 - NSISdl doesn't handle files over 2GB and patch #1656076 - make NSISdl more "translator-friendly" git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5175 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/NSISdl/ReadMe.txt | 20 ++++- Contrib/NSISdl/SConscript | 7 +- Contrib/NSISdl/httpget.h | 3 +- Contrib/NSISdl/nsisdl.cpp | 158 ++++++++++++++++++++++++++++---------- Contrib/NSISdl/util.cpp | 76 ++++++++++++++++++ Contrib/NSISdl/util.h | 2 + 6 files changed, 220 insertions(+), 46 deletions(-) diff --git a/Contrib/NSISdl/ReadMe.txt b/Contrib/NSISdl/ReadMe.txt index db474a9f..db98b436 100644 --- a/Contrib/NSISdl/ReadMe.txt +++ b/Contrib/NSISdl/ReadMe.txt @@ -59,6 +59,22 @@ TRANSLATE To translate NSISdl add the following values to the call line: +/TRANSLATE2 downloading connecting second minute hour seconds minutes hours progress + +Default values are: + + downloading - "Downloading %s" + connecting - "Connecting ..." + second - " (1 second remaining)" + minute - " (1 minute remaining)" + hour - " (1 hour remaining)" + seconds - " (%u seconds remaining)" + minutes - " (%u minutes remaining)" + hours - " (%u hours remaining)" + progress - "%skB (%d%%) of %skB @ %u.%01ukB/s" + +The old /TRANSLATE method still works for backward compatibility. + /TRANSLATE downloading connecting second minute hour plural progress remianing Default values are: @@ -69,7 +85,7 @@ Default values are: minute - "minute" hour - "hour" plural - "s" - progress - "%dkB (%d%%) of %dkB @ %d.%01dkB/s" + progress - "%dkB (%d%%) of %ukB @ %d.%01dkB/s" remaining - " (%d %s%s remaining)" -/TRANSLATE must come before /TIMEOUT. \ No newline at end of file +/TRANSLATE and /TRANSLATE2 must come before /TIMEOUT. diff --git a/Contrib/NSISdl/SConscript b/Contrib/NSISdl/SConscript index e18bae07..101aa155 100644 --- a/Contrib/NSISdl/SConscript +++ b/Contrib/NSISdl/SConscript @@ -22,4 +22,9 @@ docs = Split(""" Import('BuildPlugin') -BuildPlugin(target, files, libs, docs = docs, cppused = True) +BuildPlugin( + target, files, libs, + docs = docs, + cppused = True, + nodeflib = False, +) diff --git a/Contrib/NSISdl/httpget.h b/Contrib/NSISdl/httpget.h index 88dc5f4b..c8b2c76a 100644 --- a/Contrib/NSISdl/httpget.h +++ b/Contrib/NSISdl/httpget.h @@ -43,6 +43,7 @@ #define _HTTPGET_H_ #include "connection.h" +#include "util.h" class JNL_HTTPGet { @@ -70,7 +71,7 @@ class JNL_HTTPGet int get_bytes(char *buf, int len); int peek_bytes(char *buf, int len); - int content_length() { char *p=getheader("content-length:"); if (p) return my_atoi(p); return 0; } + __int64 content_length() { char *p=getheader("content-length:"); if (p) return myatoi64(p); return 0; } JNL_Connection *get_con() { return m_con; } diff --git a/Contrib/NSISdl/nsisdl.cpp b/Contrib/NSISdl/nsisdl.cpp index 37348f94..40027c84 100644 --- a/Contrib/NSISdl/nsisdl.cpp +++ b/Contrib/NSISdl/nsisdl.cpp @@ -196,9 +196,24 @@ extern "C" BOOL APIENTRY DllMain(HINSTANCE _hModule, DWORD ul_reason_for_call, return TRUE; } -static int g_file_size; +#define INT32_MAX 0x7fffffff + +int MulDiv64(int nNumber, __int64 nNumerator, __int64 nDenominator) +{ + // ok, a complete implementation would handle negatives too, + // but this method is probably not generally useful. + while (nNumerator > INT32_MAX || nDenominator > INT32_MAX) + { + nNumerator = Int64ShraMod32(nNumerator, 1); + nDenominator = Int64ShraMod32(nDenominator, 1); + } + return MulDiv(nNumber, (int)nNumerator, (int)nDenominator); +} + + +static __int64 g_file_size; static DWORD g_dwLastTick = 0; -void progress_callback(char *msg, int read_bytes) +void progress_callback(char *msg, __int64 read_bytes) { // flicker reduction by A. Schiffler DWORD dwLastTick = g_dwLastTick; @@ -211,7 +226,7 @@ void progress_callback(char *msg, int read_bytes) dwLastTick = dwThisTick; } if (g_file_size) - SendMessage(g_hwndProgressBar, PBM_SETPOS, (WPARAM) MulDiv(read_bytes, 30000, g_file_size), 0); + SendMessage(g_hwndProgressBar, PBM_SETPOS, (WPARAM) MulDiv64(30000, read_bytes, g_file_size), 0); g_dwLastTick = dwLastTick; } } @@ -235,22 +250,47 @@ __declspec(dllexport) void download (HWND parent, int timeout_ms=30000; int getieproxy=1; int manualproxy=0; + int translation_version; char *error=NULL; - static char szDownloading[1024];//= "Downloading %s"; - static char szConnecting[1024];//= "Connecting ..."; - static char szSecond[1024];//= "second"; - static char szMinute[1024];//= "minute"; - static char szHour[1024];//= "hour"; - static char szPlural[1024];//= "s"; - static char szProgress[1024];//= "%dkB (%d%%) of %dkB @ %d.%01dkB/s"; - static char szRemaining[1024];//= " (%d %s%s remaining)"; + // translation version 2 & 1 + static char szDownloading[1024]; // "Downloading %s" + static char szConnecting[1024]; // "Connecting ..." + static char szSecond[1024]; // " (1 second remaining)" for v2 + // "second" for v1 + static char szMinute[1024]; // " (1 minute remaining)" for v2 + // "minute" for v1 + static char szHour[1024]; // " (1 hour remaining)" for v2 + // "hour" for v1 + static char szProgress[1024]; // "%skB (%d%%) of %skB at %u.%01ukB/s" for v2 + // "%dkB (%d%%) of %dkB at %d.%01dkB/s" for v1 + + // translation version 2 only + static char szSeconds[1024]; // " (%u seconds remaining)" + static char szMinutes[1024]; // " (%u minutes remaining)" + static char szHours[1024]; // " (%u hours remaining)" + + // translation version 1 only + static char szPlural[1024]; // "s"; + static char szRemaining[1024]; // " (%d %s%s remaining)"; EXDLL_INIT(); popstring(url); - if (!lstrcmpi(url, "/TRANSLATE")) { + if (!lstrcmpi(url, "/TRANSLATE2")) { + popstring(szDownloading); + popstring(szConnecting); + popstring(szSecond); + popstring(szMinute); + popstring(szHour); + popstring(szSeconds); + popstring(szMinutes); + popstring(szHours); + popstring(szProgress); + popstring(url); + translation_version=2; + } else if (!lstrcmpi(url, "/TRANSLATE")) { popstring(szDownloading); popstring(szConnecting); popstring(szSecond); @@ -260,16 +300,18 @@ __declspec(dllexport) void download (HWND parent, popstring(szProgress); popstring(szRemaining); popstring(url); - } - else { + translation_version=1; + } else { lstrcpy(szDownloading, "Downloading %s"); lstrcpy(szConnecting, "Connecting ..."); - lstrcpy(szSecond, "second"); - lstrcpy(szMinute, "minute"); - lstrcpy(szHour, "hour"); - lstrcpy(szPlural, "s"); - lstrcpy(szProgress, "%dkB (%d%%) of %dkB @ %d.%01dkB/s"); - lstrcpy(szRemaining, " (%d %s%s remaining)"); + lstrcpy(szSecond, " (1 second remaining)"); + lstrcpy(szMinute, " (1 minute remaining)"); + lstrcpy(szHour, " (1 hour remaining)"); + lstrcpy(szSeconds, " (%u seconds remaining)"); + lstrcpy(szMinutes, " (%u minutes remaining)"); + lstrcpy(szHours, " (%u hours remaining)"); + lstrcpy(szProgress, "%skB (%d%%) of %skB at %u.%01ukB/s"); + translation_version=2; } lstrcpyn(buf, url, 10); if (!lstrcmpi(buf, "/TIMEOUT=")) { @@ -356,9 +398,9 @@ __declspec(dllexport) void download (HWND parent, get=new JNL_HTTPGet(JNL_CONNECTION_AUTODNS,16384,(p&&p[0])?p:NULL); int st; int has_printed_headers = 0; - int cl = 0; + __int64 cl = 0; int len; - int sofar = 0; + __int64 sofar = 0; DWORD last_recv_time=start_time; get->addheader ("User-Agent: NSISDL/1.2 (Mozilla)"); @@ -437,31 +479,63 @@ __declspec(dllexport) void download (HWND parent, WriteFile(hFile,buf,len,&dw,NULL); sofar += len; int time_sofar=(GetTickCount()-start_time)/1000; - int bps=sofar/(time_sofar?time_sofar:1); - int remain=MulDiv(time_sofar,cl,sofar) - time_sofar; - char *rtext=szSecond; - if (remain >= 60) - { - remain/=60; - rtext=szMinute; + int bps = (int)(sofar/(time_sofar?time_sofar:1)); + int remain = MulDiv64(time_sofar, cl, sofar) - time_sofar; + + if (translation_version == 2) { + char *rtext=remain==1?szSecond:szSeconds;; if (remain >= 60) { remain/=60; - rtext=szHour; + rtext=remain==1?szMinute:szMinutes; + if (remain >= 60) + { + remain/=60; + rtext=remain==1?szHour:szHours; + } } + + char sofar_str[128]; + char cl_str[128]; + myitoa64(sofar/1024, sofar_str); + myitoa64(cl/1024, cl_str); + + wsprintf (buf, + szProgress, //%skB (%d%%) of %skB @ %u.%01ukB/s + sofar_str, + MulDiv64(100, sofar, cl), + cl_str, + bps/1024,((bps*10)/1024)%10 + ); + if (remain) wsprintf(buf+lstrlen(buf),rtext, + remain + ); + } else if (translation_version == 1) { + char *rtext=szSecond; + if (remain >= 60) + { + remain/=60; + rtext=szMinute; + if (remain >= 60) + { + remain/=60; + rtext=szHour; + } + } + + wsprintf (buf, + szProgress, //%dkB (%d%%) of %dkB @ %d.%01dkB/s + int(sofar), + MulDiv64(100, sofar, cl), + int(cl), + bps/1024,((bps*10)/1024)%10 + ); + if (remain) wsprintf(buf+lstrlen(buf),szRemaining, + remain, + rtext, + remain==1?"":szPlural + ); } - wsprintf (buf, - szProgress, - sofar/1024, - MulDiv(100,sofar,cl), - cl/1024, - bps/1024,((bps*10)/1024)%10 - ); - if (remain) wsprintf(buf+lstrlen(buf),szRemaining, - remain, - rtext, - remain==1?"":szPlural - ); progress_callback(buf, sofar); } else { if (sofar < cl) diff --git a/Contrib/NSISdl/util.cpp b/Contrib/NSISdl/util.cpp index 6c860b34..6d17e009 100644 --- a/Contrib/NSISdl/util.cpp +++ b/Contrib/NSISdl/util.cpp @@ -26,6 +26,82 @@ int my_atoi(char *s) return (int)v; } +// Updated for int64 and simple bitwise operations +__int64 myatoi64(char *s) +{ + __int64 v=0; + // Check for right input + if (!s) return 0; + if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) + { + s++; + for (;;) + { + int c=*(++s); + if (c >= '0' && c <= '9') c-='0'; + else if (c >= 'a' && c <= 'f') c-='a'-10; + else if (c >= 'A' && c <= 'F') c-='A'-10; + else break; + v<<=4; + v+=c; + } + } + else if (*s == '0' && s[1] <= '7' && s[1] >= '0') + { + for (;;) + { + int c=*(++s); + if (c >= '0' && c <= '7') c-='0'; + else break; + v<<=3; + v+=c; + } + } + else + { + int sign=0; + if (*s == '-') sign++; else s--; + for (;;) + { + int c=*(++s) - '0'; + if (c < 0 || c > 9) break; + v*=10; + v+=c; + } + if (sign) v = -v; + } + + // Support for simple ORed expressions + if (*s == '|') + { + v |= myatoi64(s+1); + } + + return v; +} + +void myitoa64(__int64 i, char *buffer) +{ + char buf[128], *b = buf; + + if (i < 0) + { + *(buffer++) = '-'; + i = -i; + } + if (i == 0) *(buffer++) = '0'; + else + { + while (i > 0) + { + *(b++) = '0' + ((char) (i%10)); + i /= 10; + } + while (b > buf) *(buffer++) = *(--b); + } + *buffer = 0; +} + void mini_memset(void *o,char i,int l) { char *oo=(char*)o; diff --git a/Contrib/NSISdl/util.h b/Contrib/NSISdl/util.h index 58116842..6be0704c 100644 --- a/Contrib/NSISdl/util.h +++ b/Contrib/NSISdl/util.h @@ -28,6 +28,8 @@ #define _UTIL_H_ int my_atoi(char *p); +__int64 myatoi64(char *s); +void myitoa64(__int64 i, char *buffer); void mini_memset(void *,char,int); void mini_memcpy(void *,void*,int);