⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ui.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ui.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 Laszlo Molnar   All Rights Reserved.   UPX and the UCL library are free software; you can redistribute them   and/or modify them under the terms of the GNU General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; see the file COPYING.   If not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Markus F.X.J. Oberhumer              Laszlo Molnar   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#include "conf.h"#include "file.h"#include "ui.h"#include "screen.h"#include "packer.h"#if 1 && defined(USE_SCREEN)#define UI_USE_SCREEN#endifenum {    M_QUIET,        // nothing at all '-qqq'    M_INFO,         // print a one line info after compression '-qq'    M_MSG,          // print "compressing", then "\r" and M_INFO    M_CB_TERM,      // 1 line callback using stdout    M_CB_SCREEN     // 2 line callback using screen};struct UiPacker::State{    int mode;    unsigned u_len;    unsigned step;    unsigned next_update;    int pass;    int total_passes;    // message stuff    char msg_buf[1+79+1];    int pos;                // last progress bar position    unsigned spin_counter;  // for spinner    int bar_pos;    int bar_len;    int pass_digits;        // number of digits needed to print total_passes#if defined(UI_USE_SCREEN)    screen_t *screen;    int screen_init_done;    int b_cx, b_cy;    int s_cx, s_cy;    int s_fg, s_bg;    int c_fg;    int scroll_up;    int cursor_shape;#else    void *screen;#endif};long UiPacker::total_files = 0;long UiPacker::total_files_done = 0;long UiPacker::total_c_len = 0;long UiPacker::total_u_len = 0;long UiPacker::total_fc_len = 0;long UiPacker::total_fu_len = 0;long UiPacker::update_c_len = 0;long UiPacker::update_u_len = 0;long UiPacker::update_fc_len = 0;long UiPacker::update_fu_len = 0;/*************************************************************************// constants**************************************************************************/static const char header_line1[] =    "        File size         Ratio      Format      Name\n";static char header_line2[] =    "   --------------------   ------   -----------   -----------\n";static char progress_filler[] = ".*[]";static void init_global_constants(void){#if 0 && (ACC_OS_DOS16 || ACC_OS_DOS32)    // FIXME: should test codepage here    static bool done = false;    if (done)        return;    done = true;#if 1 && defined(__DJGPP__)    /* check for Windows NT/2000/XP */    if (_get_dos_version(1) == 0x0532)        return;#endif    char *p;    for (p = header_line2; *p; p++)        if (*p == '-')            *p = '\xc4';    //strcpy(progress_filler, "\x07\xb0[]");    //strcpy(progress_filler, "\x07\xb1[]");    strcpy(progress_filler, "\xf9\xfe[]");#endif}/*************************************************************************//**************************************************************************/static const char *mkline(unsigned long fu_len, unsigned long fc_len,                          unsigned long u_len, unsigned long c_len,                          const char *format_name, const char *filename,                          bool decompress=false){    static char buf[2048];    char r[7+1];    char fn[13+1];    const char *f;    // Large ratios can happen because of overlays that are    // appended after a program is packed.    unsigned ratio = get_ratio(fu_len, fc_len) + 50;#if 1    if (ratio >= 1000*1000)        strcpy(r, "overlay");#else    if (ratio >= 10*1000*1000)      // >= "1000%"        strcpy(r, "999.99%");#endif    else        upx_snprintf(r, sizeof(r), "%3u.%02u%%", ratio / 10000, (ratio % 10000) / 100);    if (decompress)        f = "%10ld <-%10ld  %7s  %13s  %s";    else        f = "%10ld ->%10ld  %7s  %13s  %s";    center_string(fn, sizeof(fn), format_name);    assert(strlen(fn) == 13);    upx_snprintf(buf, sizeof(buf), f, fu_len, fc_len, r, fn, filename);    UNUSED(u_len); UNUSED(c_len);    return buf;}/*************************************************************************//**************************************************************************/UiPacker::UiPacker(const Packer *p_) :    ui_pass(0), ui_total_passes(0), p(p_), s(NULL){    init_global_constants();    cb.reset();    s = new State;    memset(s,0,sizeof(*s));    s->msg_buf[0] = '\r';#if defined(UI_USE_SCREEN)    // FIXME - ugly hack    s->screen = sobject_get_screen();#endif    if (opt->verbose < 0)        s->mode = M_QUIET;    else if (opt->verbose == 0 || !acc_isatty(STDOUT_FILENO))        s->mode = M_INFO;    else if (opt->verbose == 1 || opt->no_progress)        s->mode = M_MSG;    else if (s->screen == NULL)        s->mode = M_CB_TERM;    else        s->mode = M_CB_SCREEN;}UiPacker::~UiPacker(){    cb.reset();    delete s; s = NULL;}/*************************************************************************// start callback**************************************************************************/void UiPacker::printInfo(int nl){    if (opt->all_methods && s->total_passes > 1)        con_fprintf(stdout, "Compressing %s [%s]%s", p->fi->getName(), p->getName(), nl ? "\n" : "");    else    {        char method_name[32+1];        set_method_name(method_name, sizeof(method_name), p->ph.method, p->ph.level);        con_fprintf(stdout, "Compressing %s [%s, %s]%s", p->fi->getName(), p->getName(), method_name, nl ? "\n" : "");    }}void UiPacker::startCallback(unsigned u_len, unsigned step,                             int pass, int total_passes){    s->u_len = u_len;    s->step = step;    s->next_update = step;    s->pass = pass;    s->total_passes = total_passes;    //printf("startCallback %d %d\n", s->pass, s->total_passes);    s->bar_len = 64;    s->pos = -2;    s->spin_counter = 0;    s->bar_pos = 1;             // because of the leading '\r'    s->pass_digits = 0;    cb.reset();    if (s->pass < 0)            // no callback wanted        return;    if (s->mode <= M_INFO)        return;    if (s->mode == M_MSG)    {        if (pass <= 1)        {            printInfo(0);            fflush(stdout);            printSetNl(2);        }        return;    }#if (ACC_CC_MSC && (_MSC_VER == 1300))    cb.nprogress = &UiPacker::progress_callback;#else    cb.nprogress = progress_callback;#endif    cb.user = this; // parameter for static function UiPacker::progress_callback()    if (s->mode == M_CB_TERM)    {        const char *fname = fn_basename(p->fi->getName());        int l = (int) strlen(fname);        if (l > 0 && l <= 30)        {            strcpy(&s->msg_buf[s->bar_pos], fname);            s->bar_pos += l;            s->msg_buf[s->bar_pos++] = ' ';            s->msg_buf[s->bar_pos++] = ' ';            s->bar_len -= l + 2;        }    }    // set pass    if (total_passes > 1)    {        int buflen, l;        do {            s->pass_digits++;            total_passes /= 10;        } while (total_passes > 0);        buflen = sizeof(s->msg_buf) - s->bar_pos;        l = upx_snprintf(&s->msg_buf[s->bar_pos], buflen, "%*d/%*d  ",                         s->pass_digits, s->pass,                         s->pass_digits, s->total_passes);        if (l > 0 && s->bar_len - l > 10)        {            s->bar_len -= l;            s->bar_pos += l;        }    }#if defined(UI_USE_SCREEN)    if (s->mode == M_CB_SCREEN)    {        if (!s->screen_init_done)        {            s->screen_init_done = 1;            if (s->screen->hideCursor)                s->cursor_shape = s->screen->hideCursor(s->screen);            s->s_fg = s->screen->getFg(s->screen);            s->s_bg = s->screen->getBg(s->screen);            s->screen->getCursor(s->screen,&s->s_cx,&s->s_cy);            s->scroll_up = s->screen->getScrollCounter(s->screen);            printInfo(1);            s->screen->getCursor(s->screen,&s->b_cx,&s->b_cy);            s->scroll_up = s->screen->getScrollCounter(s->screen) - s->scroll_up;        }    }#endif /* UI_USE_SCREEN */}// may only get called directly after startCallback()void UiPacker::firstCallback(){    if (s->pos == -2)        doCallback(0, 0);}// make sure we reach 100% in the progress barvoid UiPacker::finalCallback(unsigned u_len, unsigned c_len){    s->next_update = u_len;    doCallback(u_len, c_len);}/*************************************************************************// end callback**************************************************************************/void UiPacker::endCallback(){    bool done = (s->total_passes <= 0 || s->pass >= s->total_passes);    endCallback(done);}void UiPacker::endCallback(bool done){    if (s->pass < 0)            // no callback wanted        return;    if (s->mode == M_CB_TERM)    {        if (done)            printClearLine(stdout);        else            printSetNl(2);    }    // restore screen#if defined(UI_USE_SCREEN)    if (s->mode == M_CB_SCREEN)    {        if (done)        {            int cx, cy, sy;            assert(s->screen_init_done);            s->screen_init_done = 0;            assert(s->s_cx == 0 && s->b_cx == 0);            s->screen->getCursor(s->screen, &cx, &cy);            sy = UPX_MAX(0, s->s_cy - s->scroll_up);            while (cy >= sy)                s->screen->clearLine(s->screen, cy--);            s->screen->setCursor(s->screen, s->s_cx, sy);            s->screen->setFg(s->screen,s->s_fg);            s->screen->setBg(s->screen,s->s_bg);            if (s->cursor_shape > 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -