home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
programm
/
utility
/
resgrep0.lzh
/
ResGrep
/
src
/
resources.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-11
|
12KB
|
533 lines
//
// Die Implementation der drei Klassen:
//
// -- ResFile: enthΣlt die Daten eines ResourceFiles
//
// -- ResType: verwaltet eine Typeliste
//
// -- ResID: verwaltet eine Resource.
//
//
// 22.03.1992 Andre geschrieben
//
#include <unistd.h>
#include <stdlib.h>
#include "resources.h"
#include "utils.h"
#include "export.h"
#define ONE ((size_t)1)
// ----------------------------------------------------------------------
//
// Die Methoden fⁿr ResID
//
ResID::ResID(MacResID *mri, unsigned long theResType,
void *theMacResNameList, unsigned long FileDataOffset)
: node(NULL, nocopy, mri->ID, theResType)
{
if( mri->NameOffset!=-1 ) // Nur wenn es einen Namen gibt diesen eintragen
node::setname( pstr2cstr( theMacResNameList+mri->NameOffset ) );
Attrs = mri->Attrs;
DataOffset = mri->DataOffset + FileDataOffset;
}
ResID::~ResID(void)
{
}
int ResID::export(void)
{
extern FILE *globalFile;
return exportres(getpack(),globalFile,DataOffset);
}
#if 0
int ResID::export(void)
{
unsigned long len;
FILE *out;
extern FILE *globalFile;
char *buffer;
if( (out=fopen("T:ResGrepOut","w"))==NULL )
{
printf("Kann OutFile nicht ÷ffnen.\n");
return 1;
}
printf("Lese Daten ab: %5d\n",DataOffset);
if( fseek(globalFile,(long)DataOffset,SEEK_SET)!=0 )
{
printf("Fehler bei fseek.\n");
return 2;
}
// LΣnge bestimmen.
if( fread( (void *)&len, sizeof(unsigned long), ONE, globalFile)!=ONE )
{
printf("Fehler bei fread.\n");
return 3;
}
printf("LΣnge der Daten: %d\n",len);
if( (buffer=(char *)malloc(len))==NULL )
{
printf("Fehler bei malloc.\n");
return 4;
}
if( fread((void *)buffer,sizeof(char),len,globalFile)!=len )
{
printf("Fehler bei fread (2).\n");
return 5;
}
if( fwrite( (void *)buffer,sizeof(char),len,out)!=len )
{
printf("Fehler bei fwrite.\n");
return 6;
}
fclose(out);
free(buffer);
return 0;
}
#endif
//---------------------------------------------------------------------------
//
// Die Methoden fⁿr ResType
//
ResType::ResType(MacResType *mrt, MacResID *mri, void *theMacResNameList,
unsigned long FileDataOffset, char *name, long pri)
: node(name, nocopy, pri, mrt->theResType)
, theResID()
{
NumberOfResIDs = mrt->NumberOfResRef + 1;
for(int index=0; index<NumberOfResIDs; index++)
{
ResID *ri;
// Auch hier ein neues Listenelement belegen und initialisieren.
ri= new ResID(&mri[index], mrt->theResType, theMacResNameList,
FileDataOffset);
theResID.enqueuepri(ri);
}
}
ResType::~ResType(void)
{
node *n;
while( (n=theResID.remhead())!=NULL )
delete ((ResID *)n);
}
void ResType::hidewin(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg->IDCMPWindow==NULL )
return;
// Bei NULL auf jeden Fall verstecken.
if( msg==NULL )
theResID.hide();
n=theResID.checkdis(msg);
if( msg->IDCMPWindow==NULL )
theResID.hide();
}
void ResType::revealwin(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg->IDCMPWindow==NULL )
return;
// Bei NULL auf jeden Fall hervorkommen lassen
if( msg==NULL )
theResID.reveal();
n=theResID.checkdis(msg);
if( msg->IDCMPWindow==NULL )
theResID.reveal();
}
void ResType::closewin(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg->IDCMPWindow==NULL )
return;
// Bei NULL auf jeden Fall schliessen
if( msg==NULL )
theResID.closedis();
n=theResID.checkdis(msg);
if( msg->IDCMPWindow==NULL )
theResID.closedis();
}
void ResType::displaywin(struct MsgPort *mp, struct Menu *menu)
{
static char buffer[256];
sprintf(buffer,"Resgrep - IDs of Type '%4s' from [%ld] %s",
pack2cstr(node::getpack()),getpri(),getname());
if( theResID.display(mp,menu,readwrite,"pn",35,6,NewXPos(),NewYPos(),
buffer+22, buffer)==0)
CoordsUsed();
}
node *ResType::check(struct IntuiMessage *msg)
{
node *n;
int er;
// Fehler abfangen.
if( msg->IDCMPWindow==NULL )
return NULL;
// Ist das aktuelle Fenster (also das Type-Fenster (Inhalt: verschiedene
// IDs)) gemeint?
n=theResID.checkdis(msg);
if( msg->IDCMPWindow==NULL ) // Das Fenster war gemeint!
{
if( n!=NULL )
{
er=((ResID *)n)->export();
if( er!=ERR_NO )
ResError("Error during data export.");
return NULL;
}
else
return NULL;
}
return NULL;
}
//---------------------------------------------------------------------------
//
// Die Methoden zu ResFile
//
ResFile::ResFile(void) : node(NULL), theResType()
{
// Initialisierung und der Versuch eine Datei zu ÷ffnen.
fullname=NULL;
fp=NULL;
NumberOfResTypes=0;
DataOffset=0;
Attrs=0;
}
ResFile::~ResFile(void)
{
node *n;
close();
while( (n=theResType.remhead())!=NULL )
{
((ResType *)n)->closewin(NULL);
delete ((ResType *)n);
}
}
// ╓ffnet ein Resourcefile. 0=Alles OK. Sonst: Fehler.
// Die Fehler im einzelnen:
// 0: Kein Fehler
// 1: Kann File nicht ÷ffnen
// 2: File nicht in Ordnung (festgestellt beim Einlesen vom ResHeader)
// 3: Kein Speicher fⁿr ResMap
// 4: File nicht in Ordnung (festgestellt beim Einlesen vom ResMapHeader)
int ResFile::open(char *name)
{
MacResHeader theMacResHeader; // Da ist der ResFile Header drin.
void *theMacMap; // Eine Kopie der ganzen ResMap im Speicher.
MacResMapHeader *theMacResMapHeader; // Den Anfang dieser MacMap bildet
// der MacResMapHeader.
MacResFile *theMacResFile; // Die Resource Type Liste,
// enthΣlt die Anzahl der verschiedenen
// Recourcetypen und die Resourcetypen
// selbst.
void *theMacResNameList; // Der Zeiger auf den Anfang der
// Namen der Resourcen.
if( name==NULL )
name=ASLGetName();
node::setname(name);
if( (fp=fopen(name,"r"))==NULL ) // Der Versuch, das File zum lesen
return 1; // zu ÷ffnen.
rewind(fp); // Das File zurⁿcksetzen.
// Dann den Resource File Header einlesen.
if( fread( (void *)&theMacResHeader, ONE, sizeof(MacResHeader),fp )
!= sizeof(MacResHeader) )
return 2;
DataOffset = theMacResHeader.DataOffset;
// Die ResMap einlesen:
if( (theMacMap=malloc(theMacResHeader.MapLength))==NULL )
return 3;
if( fseek(fp,theMacResHeader.MapOffset,SEEK_SET) )
{
free(theMacMap);
return 4;
}
if( fread(theMacMap, ONE, (size_t)theMacResHeader.MapLength,fp)
!= (size_t)theMacResHeader.MapLength )
{
free(theMacMap);
return 4;
}
// Dann die neue Filenummer festlegen.
setpri(GetNewFileNum());
// Dann erstmal nachsehen, ob das
// Eingelesene zu gebrauchen ist.
theMacResMapHeader = (MacResMapHeader *)theMacMap;
Attrs = theMacResMapHeader->Attrs;
theMacResFile = (MacResFile *)( ((char *)theMacMap)
+ theMacResMapHeader->TypeListOffset);
NumberOfResTypes = theMacResFile->Number;
theMacResNameList = (MacResFile *)( ((char *)theMacMap)
+ theMacResMapHeader->NameListOffset);
for(int index=0; index<=theMacResFile->Number; index++)
{
// Fⁿr jeden Resource-Typen ein ResType-Objekt anlegen
ResType *rt;
rt=new ResType(&(theMacResFile->Type[index]),
(MacResID *)(((char *)theMacResFile) +
theMacResFile->Type[index].RefListOffset),
theMacResNameList,
DataOffset,
name, node::getpri());
// Und dann noch tierisch wichtige Sachen initialisieren:
// rt->setname( node::getname() );
// rt->setpri( node::getpri() );
theResType.enqueuepack(rt);
}
return 0;
}
void ResFile::close(void)
{
fclose(fp);
}
FILE *ResFile::getfp(void)
{
return fp;
}
// Die Fensterfunktionen fⁿr das ResFile
void ResFile::hidewin(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg->IDCMPWindow==NULL )
return;
// Bei NULL auf jeden Fall verstecken.
if( msg==NULL )
theResType.hide();
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL )
theResType.hide();
else
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->hidewin(msg);
}
void ResFile::hidechild(struct IntuiMessage *msg)
{
node *n;
// Alle verstecken.
if( msg==NULL )
{
theResType.hide();
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->hidewin(NULL);
return;
}
if(msg!=NULL && msg->IDCMPWindow!=NULL )
{
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL )
{
theResType.hide();
msg=NULL;
}
}
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->hidewin(msg);
}
void ResFile::revealwin(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg==NULL )
return;
// Bei NULL auf jeden Fall hervorkommen lassen
if( msg==NULL )
theResType.reveal();
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL )
theResType.reveal();
else
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->revealwin(msg);
}
void ResFile::revealchild(struct IntuiMessage *msg)
{
node *n;
// Alle hervorholen.
if( msg==NULL )
{
theResType.reveal();
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->revealwin(NULL);
return;
}
if(msg!=NULL && msg->IDCMPWindow!=NULL )
{
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL )
{
theResType.reveal();
msg=NULL;
}
}
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->revealwin(msg);
}
void ResFile::closewin(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg==NULL || msg->IDCMPWindow==NULL )
return;
// Bei NULL auf jeden Fall schliessen
if( msg==NULL )
theResType.closedis();
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL )
theResType.closedis();
else
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->closewin(msg);
}
void ResFile::closechild(struct IntuiMessage *msg)
{
node *n;
// Alle verstecken.
if( msg==NULL )
{
theResType.closedis();
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->closewin(NULL);
return;
}
if(msg!=NULL && msg->IDCMPWindow!=NULL )
{
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL )
{
theResType.closedis();
msg=NULL;
}
}
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
((ResType *)no)->closewin(msg);
}
void ResFile::displaywin(struct MsgPort *mp, struct Menu *menu)
{
static char buffer[256];
sprintf(buffer,"Resgrep - Types from [%ld] %s",getpri(),getname());
if( theResType.display(mp,menu,readwrite,"i",6,12,NewXPos(),NewYPos(),
buffer+21,buffer)==0 )
// Koordinaten sind wirklich gebraucht worden!
CoordsUsed();
}
node *ResFile::check(struct IntuiMessage *msg)
{
node *n;
// Fehler abfangen.
if( msg->IDCMPWindow==NULL )
return NULL;
// Ist das aktuelle Fenster (also das File-Fenster (Inhalt: verschiedene
// Typen)) gemeint?
n=theResType.checkdis(msg);
if( msg->IDCMPWindow==NULL ) // Das Fenster war gemeint!
{
if( n!=NULL )
{
((ResType *)n)->
displaywin(theResType.getmp(),theResType.getmenu());
return NULL;
}
else
return NULL;
}
for(node *no=theResType.getfirst(); no->getsucc(); no=no->getsucc())
{
n=((ResType *)no)->check(msg);
if( msg->IDCMPWindow==NULL )
return n;
}
return NULL;
}