home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Cruncher / XPK416SR.LHA / xpk_Source / shell / xBench.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-06  |  11.1 KB  |  477 lines

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