home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / programm / utility / resgrep0.lzh / ResGrep / src / resources.cc < prev    next >
C/C++ Source or Header  |  1992-04-11  |  12KB  |  533 lines

  1. //
  2. // Die Implementation der drei Klassen:
  3. //
  4. // -- ResFile:    enthΣlt die Daten eines ResourceFiles
  5. //
  6. // -- ResType:    verwaltet eine Typeliste
  7. //
  8. // -- ResID:    verwaltet eine Resource.
  9. //
  10. //
  11. // 22.03.1992 Andre    geschrieben
  12. //
  13.  
  14. #include <unistd.h>
  15. #include <stdlib.h>
  16. #include "resources.h"
  17. #include "utils.h"
  18. #include "export.h"
  19.  
  20. #define ONE ((size_t)1)
  21.  
  22. // ----------------------------------------------------------------------
  23. //
  24. // Die Methoden fⁿr ResID
  25. //
  26.  
  27. ResID::ResID(MacResID *mri, unsigned long theResType,
  28.          void *theMacResNameList, unsigned long FileDataOffset)
  29.       : node(NULL, nocopy, mri->ID, theResType)
  30. {
  31.    if( mri->NameOffset!=-1 ) // Nur wenn es einen Namen gibt diesen eintragen
  32.       node::setname( pstr2cstr( theMacResNameList+mri->NameOffset ) );
  33.    Attrs = mri->Attrs;
  34.    DataOffset = mri->DataOffset + FileDataOffset;
  35. }
  36.  
  37. ResID::~ResID(void)
  38. {
  39. }
  40.  
  41. int ResID::export(void)
  42. {
  43.    extern FILE *globalFile;
  44.  
  45.    return exportres(getpack(),globalFile,DataOffset);
  46. }
  47.  
  48. #if 0
  49. int ResID::export(void)
  50. {
  51.    unsigned long   len;
  52.    FILE *out;
  53.    extern FILE *globalFile;
  54.    char  *buffer;
  55.  
  56.    if( (out=fopen("T:ResGrepOut","w"))==NULL )
  57.    {
  58.       printf("Kann OutFile nicht ÷ffnen.\n");
  59.       return 1;
  60.    }
  61.    printf("Lese Daten ab: %5d\n",DataOffset);
  62.  
  63.    if( fseek(globalFile,(long)DataOffset,SEEK_SET)!=0 )
  64.    {
  65.       printf("Fehler bei fseek.\n");
  66.       return 2;
  67.    }
  68.  
  69.    // LΣnge bestimmen.
  70.    if( fread( (void *)&len, sizeof(unsigned long), ONE, globalFile)!=ONE )
  71.    {
  72.       printf("Fehler bei fread.\n");
  73.       return 3;
  74.    }
  75.  
  76.    printf("LΣnge der Daten: %d\n",len);
  77.  
  78.    if( (buffer=(char *)malloc(len))==NULL )
  79.    {
  80.       printf("Fehler bei malloc.\n");
  81.       return 4;
  82.    }
  83.  
  84.    if( fread((void *)buffer,sizeof(char),len,globalFile)!=len )
  85.    {
  86.       printf("Fehler bei fread (2).\n");
  87.       return 5;
  88.    }
  89.    if( fwrite( (void *)buffer,sizeof(char),len,out)!=len )
  90.    {
  91.       printf("Fehler bei fwrite.\n");
  92.       return 6;
  93.    }
  94.    fclose(out);
  95.    free(buffer);
  96.    return 0;
  97. }
  98. #endif
  99.  
  100.  
  101. //---------------------------------------------------------------------------
  102. //
  103. // Die Methoden fⁿr ResType
  104. //
  105.  
  106. ResType::ResType(MacResType *mrt, MacResID *mri, void *theMacResNameList,
  107.          unsigned long FileDataOffset, char *name, long pri)
  108.     : node(name, nocopy, pri, mrt->theResType)
  109.     , theResID()
  110. {
  111.    NumberOfResIDs = mrt->NumberOfResRef + 1;
  112.  
  113.    for(int index=0; index<NumberOfResIDs; index++)
  114.    {
  115.       ResID *ri;
  116.  
  117.       // Auch hier ein neues Listenelement belegen und initialisieren.
  118.       ri= new ResID(&mri[index], mrt->theResType, theMacResNameList,
  119.             FileDataOffset);
  120.       theResID.enqueuepri(ri);
  121.    }
  122. }
  123.  
  124. ResType::~ResType(void)
  125. {
  126.    node *n;
  127.  
  128.    while( (n=theResID.remhead())!=NULL )
  129.       delete ((ResID *)n);
  130. }
  131.  
  132. void ResType::hidewin(struct IntuiMessage *msg)
  133. {
  134.    node *n;
  135.  
  136.    // Fehler abfangen.
  137.    if( msg->IDCMPWindow==NULL )
  138.       return;
  139.  
  140.    // Bei NULL auf jeden Fall verstecken.
  141.    if( msg==NULL )
  142.       theResID.hide();
  143.  
  144.    n=theResID.checkdis(msg);
  145.    if( msg->IDCMPWindow==NULL )
  146.       theResID.hide();
  147. }
  148.  
  149. void ResType::revealwin(struct IntuiMessage *msg)
  150. {
  151.    node *n;
  152.  
  153.    // Fehler abfangen.
  154.    if( msg->IDCMPWindow==NULL )
  155.       return;
  156.  
  157.    // Bei NULL auf jeden Fall hervorkommen lassen
  158.    if( msg==NULL )
  159.       theResID.reveal();
  160.  
  161.    n=theResID.checkdis(msg);
  162.    if( msg->IDCMPWindow==NULL )
  163.       theResID.reveal();
  164. }
  165.  
  166. void ResType::closewin(struct IntuiMessage *msg)
  167. {
  168.    node *n;
  169.  
  170.    // Fehler abfangen.
  171.    if( msg->IDCMPWindow==NULL )
  172.       return;
  173.  
  174.    // Bei NULL auf jeden Fall schliessen
  175.    if( msg==NULL )
  176.       theResID.closedis();
  177.  
  178.    n=theResID.checkdis(msg);
  179.    if( msg->IDCMPWindow==NULL )
  180.       theResID.closedis();
  181. }
  182.  
  183. void ResType::displaywin(struct MsgPort *mp, struct Menu *menu)
  184. {
  185.    static char buffer[256];
  186.  
  187.    sprintf(buffer,"Resgrep - IDs of Type '%4s' from [%ld] %s",
  188.        pack2cstr(node::getpack()),getpri(),getname());
  189.    if( theResID.display(mp,menu,readwrite,"pn",35,6,NewXPos(),NewYPos(),
  190.             buffer+22, buffer)==0)
  191.       CoordsUsed();
  192. }
  193.  
  194. node *ResType::check(struct IntuiMessage *msg)
  195. {
  196.    node *n;
  197.    int er;
  198.  
  199.    // Fehler abfangen.
  200.    if( msg->IDCMPWindow==NULL )
  201.       return NULL;
  202.    // Ist das aktuelle Fenster (also das Type-Fenster (Inhalt: verschiedene
  203.    // IDs)) gemeint?
  204.    n=theResID.checkdis(msg);
  205.    if( msg->IDCMPWindow==NULL )  // Das Fenster war gemeint!
  206.    {
  207.       if( n!=NULL )
  208.       {
  209.      er=((ResID *)n)->export();
  210.      if( er!=ERR_NO )
  211.         ResError("Error during data export.");
  212.      return NULL;
  213.       }
  214.       else
  215.      return NULL;
  216.    }
  217.    return NULL;
  218. }
  219.  
  220.  
  221. //---------------------------------------------------------------------------
  222. //
  223. // Die Methoden zu ResFile
  224. //
  225.  
  226. ResFile::ResFile(void) : node(NULL), theResType()
  227. {
  228.    // Initialisierung und der Versuch eine Datei zu ÷ffnen.
  229.    fullname=NULL;
  230.    fp=NULL;
  231.    NumberOfResTypes=0;
  232.    DataOffset=0;
  233.    Attrs=0;
  234. }
  235.  
  236. ResFile::~ResFile(void)
  237. {
  238.    node *n;
  239.  
  240.    close();
  241.    while( (n=theResType.remhead())!=NULL )
  242.    {
  243.       ((ResType *)n)->closewin(NULL);
  244.       delete ((ResType *)n);
  245.    }
  246. }
  247.  
  248. // ╓ffnet ein Resourcefile. 0=Alles OK. Sonst: Fehler.
  249. // Die Fehler im einzelnen:
  250. // 0:  Kein Fehler
  251. // 1:  Kann File nicht ÷ffnen
  252. // 2:  File nicht in Ordnung (festgestellt beim Einlesen vom ResHeader)
  253. // 3:  Kein Speicher fⁿr ResMap
  254. // 4:  File nicht in Ordnung (festgestellt beim Einlesen vom ResMapHeader)
  255.  
  256.  
  257. int ResFile::open(char *name)
  258. {
  259.    MacResHeader theMacResHeader; // Da ist der ResFile Header drin.
  260.    void        *theMacMap;     // Eine Kopie der ganzen ResMap im Speicher.
  261.    MacResMapHeader *theMacResMapHeader;  // Den Anfang dieser MacMap bildet
  262.                  // der MacResMapHeader.
  263.    MacResFile  *theMacResFile;     // Die Resource Type Liste,
  264.                  // enthΣlt die Anzahl der verschiedenen
  265.                  // Recourcetypen und die Resourcetypen
  266.                  // selbst.
  267.    void        *theMacResNameList;     // Der Zeiger auf den Anfang der
  268.                  // Namen der Resourcen.
  269.  
  270.    if( name==NULL )
  271.       name=ASLGetName();
  272.  
  273.    node::setname(name);
  274.    if( (fp=fopen(name,"r"))==NULL )      // Der Versuch, das File zum lesen
  275.       return 1;          // zu ÷ffnen.
  276.    rewind(fp);                   // Das File zurⁿcksetzen.
  277.  
  278.                  // Dann den Resource File Header einlesen.
  279.    if( fread( (void *)&theMacResHeader, ONE, sizeof(MacResHeader),fp )
  280.           != sizeof(MacResHeader) )
  281.       return 2;
  282.  
  283.    DataOffset = theMacResHeader.DataOffset;
  284.  
  285.                  // Die ResMap einlesen:
  286.    if( (theMacMap=malloc(theMacResHeader.MapLength))==NULL )
  287.       return 3;
  288.    if( fseek(fp,theMacResHeader.MapOffset,SEEK_SET) )
  289.    {
  290.       free(theMacMap);
  291.       return 4;
  292.    }
  293.    if( fread(theMacMap, ONE, (size_t)theMacResHeader.MapLength,fp)
  294.       != (size_t)theMacResHeader.MapLength )
  295.    {
  296.       free(theMacMap);
  297.       return 4;
  298.    }
  299.  
  300.    // Dann die neue Filenummer festlegen.
  301.  
  302.  
  303.    setpri(GetNewFileNum());
  304.  
  305.                  // Dann erstmal nachsehen, ob das
  306.                  // Eingelesene zu gebrauchen ist.
  307.    theMacResMapHeader  = (MacResMapHeader *)theMacMap;
  308.    Attrs           = theMacResMapHeader->Attrs;
  309.    theMacResFile       = (MacResFile *)( ((char *)theMacMap)
  310.                  + theMacResMapHeader->TypeListOffset);
  311.    NumberOfResTypes    = theMacResFile->Number;
  312.    theMacResNameList   = (MacResFile *)( ((char *)theMacMap)
  313.                  + theMacResMapHeader->NameListOffset);
  314.  
  315.    for(int index=0; index<=theMacResFile->Number; index++)
  316.    {
  317.       // Fⁿr jeden Resource-Typen ein ResType-Objekt anlegen
  318.       ResType *rt;
  319.  
  320.       rt=new ResType(&(theMacResFile->Type[index]),
  321.               (MacResID *)(((char *)theMacResFile) +
  322.                theMacResFile->Type[index].RefListOffset),
  323.              theMacResNameList,
  324.              DataOffset,
  325.              name, node::getpri());
  326.  
  327.       // Und dann noch tierisch wichtige Sachen initialisieren:
  328.       // rt->setname( node::getname() );
  329.       // rt->setpri( node::getpri() );
  330.  
  331.       theResType.enqueuepack(rt);
  332.    }
  333.    return 0;
  334. }
  335.  
  336. void ResFile::close(void)
  337. {
  338.    fclose(fp);
  339. }
  340.  
  341. FILE *ResFile::getfp(void)
  342. {
  343.    return fp;
  344. }
  345.  
  346.  
  347. // Die Fensterfunktionen fⁿr das ResFile
  348.  
  349. void ResFile::hidewin(struct IntuiMessage *msg)
  350. {
  351.    node *n;
  352.  
  353.    // Fehler abfangen.
  354.    if( msg->IDCMPWindow==NULL )
  355.       return;
  356.  
  357.    // Bei NULL auf jeden Fall verstecken.
  358.    if( msg==NULL )
  359.       theResType.hide();
  360.  
  361.    n=theResType.checkdis(msg);
  362.    if( msg->IDCMPWindow==NULL )
  363.       theResType.hide();
  364.    else
  365.       for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  366.      ((ResType *)no)->hidewin(msg);
  367. }
  368.  
  369. void ResFile::hidechild(struct IntuiMessage *msg)
  370. {
  371.    node *n;
  372.  
  373.    // Alle verstecken.
  374.    if( msg==NULL )
  375.    {
  376.       theResType.hide();
  377.       for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  378.      ((ResType *)no)->hidewin(NULL);
  379.       return;
  380.    }
  381.  
  382.    if(msg!=NULL && msg->IDCMPWindow!=NULL )
  383.    {
  384.       n=theResType.checkdis(msg);
  385.       if( msg->IDCMPWindow==NULL )
  386.       {
  387.      theResType.hide();
  388.      msg=NULL;
  389.       }
  390.    }
  391.  
  392.    for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  393.       ((ResType *)no)->hidewin(msg);
  394. }
  395.  
  396. void ResFile::revealwin(struct IntuiMessage *msg)
  397. {
  398.    node *n;
  399.  
  400.    // Fehler abfangen.
  401.    if( msg==NULL )
  402.       return;
  403.  
  404.    // Bei NULL auf jeden Fall hervorkommen lassen
  405.    if( msg==NULL )
  406.       theResType.reveal();
  407.  
  408.    n=theResType.checkdis(msg);
  409.    if( msg->IDCMPWindow==NULL )
  410.       theResType.reveal();
  411.    else
  412.       for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  413.      ((ResType *)no)->revealwin(msg);
  414. }
  415.  
  416. void ResFile::revealchild(struct IntuiMessage *msg)
  417. {
  418.    node *n;
  419.  
  420.    // Alle hervorholen.
  421.    if( msg==NULL )
  422.    {
  423.       theResType.reveal();
  424.       for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  425.      ((ResType *)no)->revealwin(NULL);
  426.       return;
  427.    }
  428.  
  429.    if(msg!=NULL && msg->IDCMPWindow!=NULL )
  430.    {
  431.       n=theResType.checkdis(msg);
  432.       if( msg->IDCMPWindow==NULL )
  433.       {
  434.      theResType.reveal();
  435.      msg=NULL;
  436.       }
  437.    }
  438.  
  439.    for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  440.       ((ResType *)no)->revealwin(msg);
  441. }
  442.  
  443. void ResFile::closewin(struct IntuiMessage *msg)
  444. {
  445.    node *n;
  446.  
  447.    // Fehler abfangen.
  448.    if( msg==NULL || msg->IDCMPWindow==NULL )
  449.       return;
  450.  
  451.    // Bei NULL auf jeden Fall schliessen
  452.    if( msg==NULL )
  453.       theResType.closedis();
  454.  
  455.    n=theResType.checkdis(msg);
  456.    if( msg->IDCMPWindow==NULL )
  457.       theResType.closedis();
  458.    else
  459.       for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  460.      ((ResType *)no)->closewin(msg);
  461. }
  462.  
  463. void ResFile::closechild(struct IntuiMessage *msg)
  464. {
  465.    node *n;
  466.  
  467.    // Alle verstecken.
  468.    if( msg==NULL )
  469.    {
  470.       theResType.closedis();
  471.       for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  472.      ((ResType *)no)->closewin(NULL);
  473.       return;
  474.    }
  475.  
  476.    if(msg!=NULL && msg->IDCMPWindow!=NULL )
  477.    {
  478.       n=theResType.checkdis(msg);
  479.       if( msg->IDCMPWindow==NULL )
  480.       {
  481.      theResType.closedis();
  482.      msg=NULL;
  483.       }
  484.    }
  485.  
  486.    for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  487.       ((ResType *)no)->closewin(msg);
  488. }
  489.  
  490. void ResFile::displaywin(struct MsgPort *mp, struct Menu *menu)
  491. {
  492.    static char buffer[256];
  493.  
  494.    sprintf(buffer,"Resgrep - Types from [%ld] %s",getpri(),getname());
  495.    if( theResType.display(mp,menu,readwrite,"i",6,12,NewXPos(),NewYPos(),
  496.               buffer+21,buffer)==0 )
  497.       // Koordinaten sind wirklich gebraucht worden!
  498.       CoordsUsed();
  499.  
  500. }
  501.  
  502. node *ResFile::check(struct IntuiMessage *msg)
  503. {
  504.    node *n;
  505.  
  506.    // Fehler abfangen.
  507.    if( msg->IDCMPWindow==NULL )
  508.       return NULL;
  509.    // Ist das aktuelle Fenster (also das File-Fenster (Inhalt: verschiedene
  510.    // Typen)) gemeint?
  511.    n=theResType.checkdis(msg);
  512.    if( msg->IDCMPWindow==NULL )  // Das Fenster war gemeint!
  513.    {
  514.       if( n!=NULL )
  515.       {
  516.      ((ResType *)n)->
  517.         displaywin(theResType.getmp(),theResType.getmenu());
  518.      return NULL;
  519.       }
  520.       else
  521.      return NULL;
  522.    }
  523.    for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
  524.    {
  525.       n=((ResType *)no)->check(msg);
  526.       if( msg->IDCMPWindow==NULL )
  527.      return n;
  528.    }
  529.    return NULL;
  530. }
  531.  
  532.  
  533.