home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Workbench / Archivers / xpk_Source.lha / xpk_Source / shell / xBench.c < prev    next >
C/C++ Source or Header  |  1998-03-24  |  12KB  |  515 lines

  1. #define NAME        "xBench"
  2. #define DISTRIBUTION    "(Freeware) "
  3. #define VERSION        "2"
  4. #define REVISION    "7"
  5.  
  6. /* Programmheader
  7.  
  8.         Name:           xBench
  9.         Author:         SDI (before 1.1 Urban Dominik Mⁿller)
  10.         Distribution:   PD
  11.         Description:    xpk benchmark utility
  12.         Compileropts:   -gM
  13.         Linkeropts:     -l xpkmaster amiga -gsi
  14.  
  15.  1.1   29.11.96 : added version string
  16.  1.2   20.12.96 : added output telling the caller mechanism
  17.  2.0   31.03.97 : now OS 2.0 and up only, rewritten, now an utility to
  18.         allow users making benchmarks
  19.  2.1   01.04.97 : fixed some errors
  20.  2.2   23.04.97 : fixed time calculation
  21.  2.3   10.05.97 : added ALL flag, use with care!
  22.  2.4   08.06.97 : added forgotten TAG_DONE
  23.  2.5   20.06.97 : added Pattern Matching
  24.  2.6   10.10.97 : changed output style to prevent errors on large files
  25.  2.7   24.03.98 : added third buffer for source buffer check
  26. */
  27.  
  28. #include <proto/dos.h>
  29. #include <proto/timer.h>
  30. #include <proto/xpkmaster.h>
  31. #include <proto/exec.h>
  32. #include <exec/memory.h>
  33. #include <exec/devices.h>
  34. #include "SDI_defines.h"
  35. #define SDI_TO_ANSI
  36. #include "SDI_ASM_STD_protos.h"
  37.  
  38. /* METHOD's are:
  39.  <mode - upper case, 4 chars>[.<mode - dec number>]
  40. */
  41.  
  42. #define PARAMS  "FILENAME/A,PASSWORD/K,METHOD/M,TEST/S,ALL/S,SAVE/K"
  43. #define HEADER  "Type  Num Version P    CSize   CTime    CSpd    USize   UTime    USpd  Rate\n"
  44. #define DATATXT "%s: %3ld %2ld.%ld%s %s %8ld %4ld.%02ld %7ld %8ld %4ld.%02ld %7ld %3ld.%ld\n"
  45. #define SIZEERR "%s: FileSize false after decrunching %ld != %ld\n"
  46. #define BUFERR  "%s: Decrunched buffer different to source!\n"
  47. #define SRCERR  "%s: Source buffer destroyed!\n"
  48.  
  49. struct Args {
  50.   STRPTR        filename;
  51.   STRPTR        password;
  52.   STRPTR *      method;
  53.   ULONG        test;
  54.   ULONG        all;
  55.   STRPTR    save;
  56. };
  57.  
  58. struct TestData {
  59.   STRPTR    sbuf;
  60.   STRPTR        cbuf;
  61.   ULONG        sbufsize;
  62.   STRPTR    pbuf;
  63.   ULONG        pbufsize;
  64.   STRPTR    ubuf;
  65.   ULONG        ubufsize;
  66.   STRPTR    password;
  67.   ULONG        test;
  68.   ULONG        all;
  69.   STRPTR    save;
  70.   struct FileInfoBlock *fib;
  71.   struct XpkPackerInfo *pinfo;
  72.   struct XpkMode *minfo;
  73. };
  74.  
  75. struct BenchData {
  76.   STRPTR    method;
  77.   ULONG        mode;
  78.   ULONG        version;
  79.   ULONG        revision;
  80.   STRPTR    pad;
  81.   STRPTR    password;
  82.   ULONG        CSize;
  83.   ULONG        CTime;
  84.   ULONG        CTime100;
  85.   ULONG        CSpd;
  86.   ULONG        USize;
  87.   ULONG        UTime;
  88.   ULONG        UTime100;
  89.   ULONG        USpd;
  90.   ULONG        Rate;
  91.   ULONG        Rate10;
  92. };
  93.  
  94. struct DosLibrary *     DOSBase;
  95. struct Library *        XpkBase;
  96. struct Device *     TimerBase;
  97.  
  98. ULONG DoIt(STRPTR name, struct TestData *tdat, STRPTR *method);
  99. LONG GetPackData(struct BenchData *b, struct TestData *t, STRPTR pwd);
  100. void DoTest(struct TestData *data, STRPTR method, ULONG mode);
  101. void ScanMethods(struct TestData *data, STRPTR method);
  102. void ScanPackers(struct TestData *data);
  103.  
  104. #define PATHNAME_SIZE 256
  105.  
  106. ULONG start(void) /* not named main, to get error with startup code ! */
  107. {
  108.  ULONG                  error   = RETURN_FAIL;
  109.  struct DosLibrary *    dosbase;
  110.  struct Process *       task;
  111.  
  112.  /* test for WB and reply startup-message */
  113.  if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  114.  {
  115.   WaitPort(&task->pr_MsgPort);
  116.   Forbid();
  117.   ReplyMsg(GetMsg(&task->pr_MsgPort));
  118.   return RETURN_FAIL;
  119.  }
  120.  
  121.  if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  122.  {
  123.   struct Library *xpkbase;
  124.  
  125.   DOSBase = dosbase; /* set global base */
  126.   if((xpkbase = OpenLibrary("xpkmaster.library", 4)))
  127.   {
  128.    struct RDArgs *rda;
  129.    struct Args args = {0, 0, 0, 0};
  130.  
  131.    XpkBase = xpkbase;
  132.    if((rda = ReadArgs(PARAMS, (LONG *) &args, 0)))
  133.    {
  134.     struct FileInfoBlock *fib;
  135.  
  136.     if((fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)))
  137.     {
  138.      struct AnchorPath *APath;
  139.      struct TestData tdat;
  140.      ULONG retval;
  141.  
  142.      tdat.password = args.password;
  143.      tdat.test = args.test;
  144.      tdat.all = args.all;
  145.      tdat.save = args.save;
  146.      tdat.fib = fib;
  147.  
  148.      if((APath = (struct AnchorPath *) AllocMem(sizeof(struct AnchorPath)+
  149.      PATHNAME_SIZE, MEMF_PUBLIC|MEMF_CLEAR)))
  150.      {
  151.       APath->ap_BreakBits = SIGBREAKF_CTRL_C;
  152.       APath->ap_Strlen = PATHNAME_SIZE;
  153.  
  154.       for(retval = MatchFirst(args.filename, APath); !retval; retval = MatchNext(APath))
  155.       {
  156.        if(APath->ap_Flags & APF_DIDDIR)
  157.         APath->ap_Flags &= ~APF_DIDDIR;
  158.        else if(APath->ap_Info.fib_DirEntryType > 0)
  159.        {
  160. /*        if(args.deep)
  161.          APath->ap_Flags |= APF_DODIR; */
  162.        }
  163.        else if((error = DoIt(APath->ap_Buf, &tdat, args.method)))
  164.          break;
  165.       }
  166.       MatchEnd(APath);
  167.       FreeMem(APath, sizeof(struct AnchorPath)+PATHNAME_SIZE);
  168.      }
  169.      FreeDosObject(DOS_FIB, fib);
  170.     }
  171.     FreeArgs(rda);
  172.    }
  173.    CloseLibrary(xpkbase);
  174.   }
  175.   if(error && IoErr()) /* print the error */
  176.    PrintFault(IoErr(), 0);
  177.   CloseLibrary((struct Library *) dosbase);
  178.  }
  179.  
  180.  return error;
  181. }
  182.  
  183. ULONG DoIt(STRPTR name, struct TestData *tdat, STRPTR *method)
  184. {
  185.   ULONG error = RETURN_FAIL;
  186.   ULONG fh;
  187.  
  188.   if((fh = Open(name, MODE_OLDFILE)))
  189.   {
  190.    if(ExamineFH(fh, tdat->fib))
  191.    {
  192.     tdat->sbufsize = tdat->fib->fib_Size;
  193.     tdat->ubufsize = tdat->fib->fib_Size + XPK_MARGIN;
  194.     tdat->pbufsize = tdat->fib->fib_Size + (tdat->fib->fib_Size>>5) + (XPK_MARGIN<<1);
  195.  
  196.     if((tdat->sbuf = (STRPTR) AllocMem(tdat->sbufsize, MEMF_ANY)))
  197.     {
  198.      if((tdat->ubuf = (STRPTR) AllocMem(tdat->ubufsize, MEMF_ANY|MEMF_CLEAR)))
  199.      {
  200.       if((tdat->pbuf = (STRPTR) AllocMem(tdat->pbufsize, MEMF_ANY)))
  201.       {
  202.        if(Read(fh, tdat->sbuf, tdat->sbufsize) == tdat->sbufsize)
  203.        {
  204.         struct timerequest timerequest = {0};
  205.  
  206.     if(tdat->test)
  207.     {
  208.       if((tdat->cbuf = (STRPTR) AllocMem(tdat->sbufsize, MEMF_ANY)))
  209.         CopyMem(tdat->sbuf, tdat->cbuf, tdat->sbufsize);
  210.     }
  211.     else
  212.       tdat->cbuf = 0;
  213.  
  214.         if(!OpenDevice("timer.device", UNIT_ECLOCK, (struct IORequest *)
  215.         &timerequest, 0))
  216.     {
  217.      TimerBase = timerequest.tr_node.io_Device;
  218.      if((tdat->pinfo = (struct XpkPackerInfo *)
  219.      XpkAllocObject(XPKOBJ_PACKERINFO, 0)))
  220.      {
  221.       if((tdat->minfo = (struct XpkMode *)
  222.       XpkAllocObject(XPKOBJ_MODE, 0)))
  223.       {
  224.            VPrintf("%s\n" HEADER, &name);
  225.            if(method)
  226.            {
  227.             for(;*method && !CTRL_C; ++method)
  228.             {
  229.          if(!(*method)[0] || !(*method)[1] ||
  230.          !(*method)[2] || !(*method)[3])
  231.           XpkPrintFault(XPKERR_MISSINGLIB, *method); 
  232.          else
  233.          {
  234.           (*method)[0] = toupper((*method)[0]);
  235.           (*method)[1] = toupper((*method)[1]);
  236.           (*method)[2] = toupper((*method)[2]);
  237.           (*method)[3] = toupper((*method)[3]);
  238.           if((*method)[4] == '.')
  239.               {
  240.                (*method)[4] = 0;
  241.                DoTest(tdat, *method, strtoul(*method+5, 0,10));
  242.               }
  243.               else
  244.                ScanMethods(tdat, *method);
  245.              }
  246.             }
  247.            }
  248.            else
  249.             ScanPackers(tdat);
  250.        error = 0;
  251.        XpkFreeObject(XPKOBJ_MODE, tdat->minfo);
  252.       }
  253.       XpkFreeObject(XPKOBJ_PACKERINFO, tdat->pinfo);
  254.      }
  255.      CloseDevice((struct IORequest *) &timerequest);
  256.      
  257.      if(tdat->cbuf)
  258.        FreeMem(tdat->cbuf, tdat->sbufsize);
  259.         }
  260.        }
  261.        FreeMem(tdat->pbuf, tdat->pbufsize);
  262.       }
  263.       FreeMem(tdat->ubuf, tdat->ubufsize);
  264.      }
  265.      FreeMem(tdat->sbuf, tdat->sbufsize);
  266.     }
  267.    }
  268.    Close(fh);
  269.   }
  270.   return error;
  271. }
  272.  
  273. /* These must be defined false, because this is a benchmark tool ! */
  274. static struct TagItem deftags[] = {
  275. { XPK_Preferences, FALSE},
  276. { XPK_UseXfdMaster, FALSE},
  277. { XPK_UseExternals, FALSE},
  278. { XPK_PassRequest, FALSE},
  279. { XPK_ChunkReport, FALSE},
  280. { TAG_DONE, 0},
  281. };
  282.  
  283. LONG GetPackData(struct BenchData *b, struct TestData *t, STRPTR pwd)
  284. {
  285.   struct EClockVal eval1, eval2;
  286.   LONG err, d;
  287.   ULONG freq;
  288.  
  289.   Forbid();
  290.   freq = ReadEClock(&eval1);
  291.   err = XpkPackTags(
  292.     XPK_InBuf,    t->sbuf,
  293.     XPK_InLen,    t->sbufsize,
  294.     XPK_OutBuf,    t->pbuf,
  295.     XPK_OutBufLen,    t->pbufsize,
  296.     XPK_GetOutLen,    &(b->CSize),
  297.     pwd ? XPK_Password : TAG_IGNORE,    pwd,
  298.     XPK_PackMethod,    b->method,
  299.     XPK_PackMode,    b->mode,
  300.     TAG_MORE,    deftags);
  301.   ReadEClock(&eval2);
  302.   Permit();
  303.   b->CTime = eval2.ev_lo - eval1.ev_lo;
  304.   if(err)
  305.     return err;
  306.   Forbid();
  307.   ReadEClock(&eval1);
  308.   err = XpkUnpackTags(
  309.     XPK_InBuf,    t->pbuf,
  310.     XPK_InLen,    t->pbufsize,
  311.     XPK_OutBuf,    t->ubuf,
  312.     XPK_OutBufLen,    t->ubufsize,
  313.     XPK_GetOutLen,    &d,
  314.     pwd ? XPK_Password : TAG_IGNORE, pwd,
  315.     TAG_MORE,    deftags);
  316.   ReadEClock(&eval2);
  317.   Permit();
  318.   if(err)
  319.     return err;
  320.   b->UTime = eval2.ev_lo - eval1.ev_lo;
  321.  
  322.   if(d != t->sbufsize)
  323.   {
  324.     Printf(SIZEERR, b->method, t->sbufsize, t); return 1;
  325.   }
  326.   if(t->test)
  327.   {
  328.     if(t->cbuf) /* check for destoyed source buffer */
  329.     {
  330.       for(; d && t->sbuf[d-1] == t->cbuf[d-1]; --d)
  331.         ;
  332.       if(d)
  333.       {
  334.         CopyMem(t->cbuf, t->sbuf, t->sbufsize); /* restore buffer */
  335.         memset(t->ubuf, 0, t->ubufsize);
  336.         VPrintf(SRCERR, &b->method); return 1;
  337.       }
  338.     }
  339.  
  340.     for(d = t->sbufsize; d && t->sbuf[d-1] == t->ubuf[d-1]; --d)
  341.       ;
  342.     memset(t->ubuf, 0, t->ubufsize);
  343.     if(d)
  344.     {
  345.       VPrintf(BUFERR, &b->method); return 1;
  346.     }
  347.   }
  348.  
  349.   if(t->save)
  350.   {
  351.     ULONG lock, fh;
  352.  
  353.     if((lock = Lock(t->save, SHARED_LOCK)))
  354.     {
  355.       lock = CurrentDir(lock);
  356.       if(Examine(lock, t->fib) && t->fib->fib_DirEntryType > 0)
  357.       {
  358.         UBYTE data[10];
  359.  
  360.         sprintf(data, "%.4s.%03ld", b->method, b->mode);
  361.         if((fh = Open(data, MODE_NEWFILE)))
  362.         {
  363.           Write(fh, t->pbuf, b->CSize);
  364.           Close(fh);
  365.         }
  366.       }
  367.       UnLock(CurrentDir(lock));
  368.     }
  369.   }
  370.  
  371.   if((d = 1000 - ((1000 * b->CSize)/b->USize)) < 0)
  372.     d = 0;
  373.  
  374.   b->Rate   = d/10;
  375.   b->Rate10 = d % 10;
  376.  
  377.   b->CTime100 = (100 * (b->CTime % freq)) / freq;
  378.   b->UTime100 = (100 * (b->UTime % freq)) / freq;
  379.   b->CTime /= freq;
  380.   b->UTime /= freq;
  381.  
  382.   if(!b->CTime && !b->CTime100)
  383.     b->CTime100 = 1;
  384.   if(!b->UTime && !b->UTime100)
  385.     b->UTime100 = 1;
  386.  
  387.   b->CSpd = ((100*b->USize) / ((100 * b->CTime) + b->CTime100));
  388.   b->USpd = ((100*b->USize) / ((100 * b->UTime) + b->UTime100));
  389.   return 0;
  390. }
  391.  
  392. void DoTest(struct TestData *t, STRPTR method, ULONG mode)
  393. {
  394.   struct BenchData b;
  395.   struct Library *xbase;
  396.   UBYTE libname[] = "compressors/xpk____.library";
  397.  
  398.   LONG err;
  399.  
  400.   CopyMem(method, libname+15, 4);
  401.  
  402.   if(!(xbase = OpenLibrary(libname, 0)))
  403.   {
  404.     XpkPrintFault(XPKERR_MISSINGLIB, method);
  405.     return;
  406.   }
  407.   b.version = xbase->lib_Version;
  408.   b.revision = xbase->lib_Revision;
  409.  
  410.   if(b.revision < 10)
  411.     b.pad = "   ";
  412.   else if(b.revision < 100)
  413.     b.pad = "  ";
  414.   else if(b.revision < 1000)
  415.     b.pad = " ";
  416.   else
  417.     b.pad = "";
  418.  
  419.   CloseLibrary(xbase);
  420.  
  421.   libname[19] = 0;
  422.   b.method = libname + 15;
  423.   if((b.mode = mode) > 100)
  424.     b.mode = 100;
  425.   b.USize = t->sbufsize;
  426.  
  427.   if((err = XpkQueryTags(
  428.     XPK_PackerQuery,    t->pinfo,
  429.     XPK_PackMethod,        b.method,
  430.     TAG_MORE,        deftags,
  431.     TAG_DONE)))
  432.   {
  433.     XpkPrintFault(err, b.method);
  434.     return;
  435.   }
  436.  
  437.   if((t->pinfo->xpi_Flags & XPKIF_NEEDPASSWD) && !t->password)
  438.     return;
  439.  
  440.   if((t->pinfo->xpi_Flags & XPKIF_ENCRYPTION) && t->password)
  441.   {
  442.     b.password = "*";
  443.     if((err = GetPackData(&b, t, t->password)))
  444.     {
  445.       if(err < 0)
  446.         XpkPrintFault(err, b.method);
  447.       return;
  448.     }
  449.     else
  450.       VPrintf(DATATXT, &b);
  451.   }
  452.   if(!(t->pinfo->xpi_Flags & XPKIF_NEEDPASSWD))
  453.   {
  454.     b.password = " ";
  455.     if((err = GetPackData(&b, t, 0)))
  456.     {
  457.       if(err < 0)
  458.         XpkPrintFault(err, b.method);
  459.       return;
  460.     }
  461.     else
  462.       VPrintf(DATATXT, &b);
  463.   }
  464. }
  465.  
  466. void ScanPackers(struct TestData *t)
  467. {
  468.   LONG err, i;
  469.   struct XpkPackerList *pl;
  470.  
  471.   if((pl = (struct XpkPackerList *) XpkAllocObject(XPKOBJ_PACKERLIST, 0)))
  472.   {
  473.     if((err = XpkQueryTags(
  474.     XPK_PackersQuery,    pl,
  475.     TAG_MORE,        deftags,
  476.     TAG_DONE)))
  477.     {
  478.       XpkPrintFault(err, 0); return;
  479.     }
  480.  
  481.     for(i = 0; i < pl->xpl_NumPackers && !CTRL_C; i++)
  482.       ScanMethods(t, pl->xpl_Packer[i]);
  483.  
  484.     XpkFreeObject(XPKOBJ_PACKERLIST, pl);
  485.   }
  486. }
  487.  
  488. void ScanMethods(struct TestData *t, STRPTR method)
  489. {
  490.   LONG err;
  491.   ULONG mode;
  492.  
  493.   if(t->all)
  494.   {
  495.     for(mode = 0; mode <= 100 && !CTRL_C; ++mode)
  496.      DoTest(t, method, mode);
  497.   }
  498.   else
  499.   {
  500.     for(mode = 0; mode < 100 && !CTRL_C; mode = t->minfo->xm_Upto + 1)
  501.     {
  502.       if((err = XpkQueryTags(
  503.     XPK_ModeQuery,    t->minfo,
  504.     XPK_PackMethod,    method,
  505.     XPK_PackMode,     mode,
  506.     TAG_MORE,    deftags)))
  507.       {
  508.         XpkPrintFault(err, method); return;
  509.       }
  510.       DoTest(t, method, t->minfo->xm_Upto);
  511.     }
  512.   }
  513. }
  514.  
  515.