home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of A1200
/
World_Of_A1200.iso
/
programs
/
disk
/
misc
/
tracked
/
source.lha
/
sources
/
Search.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-16
|
14KB
|
554 lines
/* Search.c routines for searching data and strings on disk */
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
struct SData
{
UWORD FirstTrack, LastTrack;
UBYTE SType;
UBYTE ByteCount;
UBYTE SearchData[40];
};
struct Requester *BlockInput();
extern struct Window *Window;
extern struct Gadget SchuifGadget;
extern struct PropInfo Schuif_info;
extern struct StringInfo Block_info, Track_info, Sector_info;
extern APTR My_VisualInfo;
extern struct TextAttr Style;
extern int drive;
extern UBYTE *BB;
extern UBYTE CursorX, CursorY, RealCursorY;
struct IOStdReq *OpenTDIO();
char *MethodsTxt[] =
{ "A = a", "A <> a", "Relative", NULL };
/* Search-modes */
#define sf_NCS 0
#define sf_Normal 1
#define sf_Rel 2
#define sf_Number 3
#define sf_total 4
/* Gadget Id's */
#define S_Method 11
#define S_Cancel 12
#define S_String 13
#define S_FTrack 14
#define S_LTrack 15
#define S_Start 16
#define S_Stop 21
UBYTE SIText[] = "Searching Track ", FIText[] = "Track ";
struct IntuiText SearchText = { 1, 0, JAM2, 0, 0, &Style, SIText, NULL };
struct NewGadget
SFTrackNG = { 32, 44, 44, 13, "Start track", &Style, S_FTrack, PLACETEXT_BELOW,
NULL, NULL },
SLTrackNG = { 136, 44, 44, 13, "End track", &Style, S_LTrack, PLACETEXT_BELOW,
NULL, NULL },
SStringNG = { 12, 16, 180, 13, "String", &Style, S_String, PLACETEXT_BELOW,
NULL, NULL },
SMethodNG = { 72, 76, 92, 12, "Case", &Style, S_Method, 0, NULL, NULL },
SCancelNG = { 124, 94, 60, 12, "Cancel", &Style, S_Cancel, 0, NULL, NULL },
SStartNG = { 20, 94, 60, 12, "Start", &Style, S_Start, 0, NULL, NULL },
SStopNG = { 46, 52, 108, 12, "Abort Search", &Style, S_Stop, 0, NULL, NULL };
void DoStringGad(gad, window, data)
struct Gadget *gad;
struct Window *window;
struct SData *data;
{
struct StringInfo *SI;
int i;
SI = (struct StringInfo *) gad->SpecialInfo;
for (i = 0; SI->Buffer[i] != 0; i++)
data->SearchData[i] = SI->Buffer[i];
data->SearchData[i] = 0;
data->ByteCount = i;
}
void DoFTrackGad(gad, window, data)
struct Gadget *gad;
struct Window *window;
struct SData *data;
{
struct StringInfo *SI;
UBYTE track;
SI = (struct StringInfo *) gad->SpecialInfo;
track = (UBYTE) SI->LongInt;
if ((track < 0) || (track > data->LastTrack))
{
track = data->FirstTrack;
sprintf(SI->Buffer, "%d\x00", data->FirstTrack);
SI->LongInt = track;
RefreshGList(gad, window, NULL, 1);
}
else data->FirstTrack = track;
}
void DoLTrackGad(gad, window, data)
struct Gadget *gad;
struct Window *window;
struct SData *data;
{
struct StringInfo *SI;
UBYTE track;
SI = (struct StringInfo *) gad->SpecialInfo;
track = (UBYTE) SI->LongInt;
if ((track < 0) || (track > 159) ||
(track < data->FirstTrack))
{
track = data->LastTrack;
sprintf(SI->Buffer, "%d\x00", track);
SI->LongInt = track;
RefreshGList(gad, window, NULL, 1);
}
else data->LastTrack = track;
}
void OpenRequester(window, data, mode)
struct Window *window;
struct SData *data;
UBYTE mode;
{
BOOL terminated = FALSE;
struct Window *SWindow;
struct IntuiMessage *imsg;
struct Gadget *gad, *glist = NULL;
struct Gadget *FTR_gad, *LTR_gad, *SS_gad;
int i;
UBYTE *title;
data->ByteCount = 0;
data->FirstTrack = 0;
data->LastTrack = 159;
data->SType = mode;
SStartNG.ng_VisualInfo = My_VisualInfo;
SCancelNG.ng_VisualInfo = My_VisualInfo;
SMethodNG.ng_VisualInfo = My_VisualInfo;
SStringNG.ng_VisualInfo = My_VisualInfo;
SFTrackNG.ng_VisualInfo = My_VisualInfo;
SLTrackNG.ng_VisualInfo = My_VisualInfo;
gad = CreateContext(&glist);
if (mode != sf_Number) gad = CreateGadget(CYCLE_KIND, gad, &SMethodNG,
GTCY_Labels, MethodsTxt, GTCY_Active, mode, TAG_END);
gad = CreateGadget(BUTTON_KIND, gad, &SStartNG, TAG_END);
gad = CreateGadget(BUTTON_KIND, gad, &SCancelNG, TAG_END);
SS_gad = gad = CreateGadget(STRING_KIND, gad, &SStringNG,
GTST_String, NULL, GTST_MaxChars, 20L, TAG_END);
gad->Activation |= GACT_STRINGCENTER;
FTR_gad = gad = CreateGadget(INTEGER_KIND, gad, &SFTrackNG,
GTIN_Number, 0L, GTIN_MaxChars, 3L, TAG_END);
gad->Activation |= GACT_STRINGCENTER;
LTR_gad = gad = CreateGadget(INTEGER_KIND, gad, &SLTrackNG,
GTIN_Number, 159L, GTIN_MaxChars, 3L, TAG_END);
gad->Activation |= GACT_STRINGCENTER;
if (mode == sf_Number) title = "Search number";
else title = "Search string";
SWindow = OpenWindowTags(NULL,
WA_Title, title,
WA_Gadgets, glist, WA_AutoAdjust, TRUE,
WA_Top, 40, WA_Left, 180,
WA_Width, 204, WA_InnerHeight, 100,
WA_DragBar, TRUE, WA_DepthGadget, TRUE,
WA_Activate, TRUE,
WA_IDCMP, CYCLEIDCMP | BUTTONIDCMP | STRINGIDCMP,
TAG_END);
if (SWindow)
{
ActivateGadget(SS_gad, SWindow, NULL);
while (!terminated)
{
Wait (1 << SWindow->UserPort->mp_SigBit);
while ((!terminated) && (imsg = GT_GetIMsg(SWindow->UserPort)))
{
switch (imsg->Class)
{
case IDCMP_GADGETUP:
gad = (struct Gadget *)imsg->IAddress;
switch(gad->GadgetID)
{
case S_Start:
DoStringGad(SS_gad, SWindow, data);
DoFTrackGad(FTR_gad, SWindow, data);
DoLTrackGad(LTR_gad, SWindow, data);
terminated = TRUE;
break;
case S_Cancel:
data->ByteCount = 0;
terminated = TRUE;
break;
case S_Method:
data->SType = imsg->Code;
break;
case S_FTrack:
DoFTrackGad(gad, SWindow, data);
break;
case S_LTrack:
DoLTrackGad(gad, SWindow, data);
break;
}
break;
}
GT_ReplyIMsg(imsg);
}
}
CloseWindow(SWindow);
}
FreeGadgets(glist);
}
BOOL Digit(ch)
UBYTE ch;
{
return((ch >= '0') && (ch <= '9'));
}
BOOL ABCDEF(ch)
UBYTE ch;
{
return(((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'Z')));
}
BOOL HexDigit(ch)
UBYTE ch;
{
return(Digit(ch) || ABCDEF(ch));
}
UBYTE HexVal(digit)
UBYTE digit;
{
if (Digit(digit)) return(digit - '0');
else return(10 + ((digit - 'a') & 0x0f));
}
UBYTE ComposeByte(dig1, dig2)
UBYTE dig1, dig2;
{
UBYTE rb;
return(16*HexVal(dig1) + HexVal(dig2));
}
int ProcessSString(string)
UBYTE *string;
{
UBYTE dstring[40];
int i, j, k;
ULONG UL;
BOOL ok = TRUE, error = FALSE;
for (i = 0; string[i] != 0; i++) dstring[i] = string[i];
dstring[i] = 0;
i = 0;
j = 0;
while (ok && !error)
{
while (dstring[i] == ' ') i++;
if (dstring[i] == '$')
{
i++;
for (k = 0; HexDigit(dstring[i+k]); k++);
if (k == 0) error = TRUE;
else while (k > 0)
{
if (k % 2)
{
string[j] = ComposeByte('0', dstring[i++]);
k--;
}
else
{
string[j] = ComposeByte(dstring[i], dstring[i+1]);
i += 2;
k -= 2;
}
j++;
}
}
else if (Digit(dstring[i]))
{
for (k = 0; Digit(dstring[i+k]); k++);
if (k > 10) error = TRUE;
else
{
UL = 0;
while (Digit(dstring[i])) UL = 10*UL + dstring[i++] - '0';
if (UL < 256) string[j++] = (UBYTE) UL;
else if (UL < 65536)
{
string[j++] = (UBYTE) (UL / 256);
string[j++] = (UBYTE) (UL & 0xff);
}
else
{
string[j++] = (UBYTE) (UL / 16777216);
string[j++] = (UBYTE) (UL / 65536);
string[j++] = (UBYTE) (UL / 256);
string[j++] = (UBYTE) (UL & 0xff);
}
}
}
else if (dstring[i] == '\'')
{
i++;
while (dstring[i] != '\'') string[j++] = dstring[i++];
i++;
}
else if (dstring[i] == 0) ok = FALSE;
else error = TRUE;
}
string[j] = 0;
if (error) j = 0;
return(j);
}
void UpDateSText(rport, track)
struct RastPort *rport;
UBYTE track;
{
sprintf(&SIText[16], " ");
sprintf(&SIText[16], "%d", track);
PrintIText(rport, &SearchText, (200-IntuiTextLength(&SearchText))/2L, 20L);
}
BOOL Match(string1, string2, n)
UBYTE *string1, *string2;
int n;
{
int i;
BOOL rc;
rc = TRUE;
i = 0;
while (rc && (i < n))
{
rc &= (string1[i] == string2[i]);
i++;
}
return(rc);
}
UBYTE UpCase(ch)
UBYTE ch;
{
if ((ch >= 'a') && (ch <= 'z')) return(ch - 'a' + 'A');
else return(ch);
}
BOOL MatchNCS(string1, string2, n)
UBYTE *string1, *string2;
int n;
{
int i;
BOOL rc;
rc = TRUE;
i = 0;
while (rc && (i < n))
{
rc &= (UpCase(string1[i]) == UpCase(string2[i]));
i++;
}
return(rc);
}
BOOL MatchRel(string1, string2, n)
BYTE *string1, *string2;
int n;
{
int i;
BYTE os;
BOOL rc;
rc = TRUE;
os = string1[0] - string2[0];
i = 1;
while ((i < n) && rc)
{
rc &= (string1[i] - string2[i] == os);
i++;
}
return(rc);
}
ULONG Search(data, drive, type)
struct SData *data;
int drive;
{
int j, n, m;
ULONG SE, OS, ROS, LTR;
BOOL eq, stop;
UBYTE *s, *tdb, *virtbuf;
struct Gadget *gad, *glist = NULL;
struct Window *SBWindow;
struct RastPort *SBRPort;
struct IntuiMessage *imsg;
BOOL (*MatchF[sf_total])();
struct IOStdReq *SearchIO;
tdb = (UBYTE *) AllocMem(2*512L, MEMF_CHIP);
if (!tdb)
{
puts("Not enough memory!");
return(0);
}
else if ((SearchIO = OpenTDIO(drive)))
{
MatchF[sf_Normal] = Match;
MatchF[sf_NCS] = MatchNCS;
MatchF[sf_Rel] = MatchRel;
MatchF[sf_Number] = Match;
SStopNG.ng_VisualInfo = My_VisualInfo;
gad = CreateContext(&glist);
gad = CreateGadget(BUTTON_KIND, gad, &SStopNG, TAG_END);
SBWindow = OpenWindowTags(NULL, WA_Title, "Searching...",
WA_Gadgets, glist, WA_AutoAdjust, TRUE,
WA_Top, 40, WA_Left, 180,
WA_Width, 200, WA_InnerHeight, 60,
WA_DragBar, TRUE, WA_DepthGadget, TRUE,
WA_Activate, TRUE,
WA_IDCMP, BUTTONIDCMP, TAG_END);
SBRPort = SBWindow->RPort;
n = data->ByteCount;
s = data->SearchData;
m = data->SType;
SE = 11*512L*(data->LastTrack + 1);
LTR = data->FirstTrack;
OS = 11*512L*LTR;
eq = FALSE;
stop = FALSE;
UpDateSText(SBRPort, (UBYTE) LTR);
while ((OS < SE) && !eq && !stop)
{
ROS = OS & 0xfffffe00;
if (ROS / (512*11) > LTR)
{
LTR = ROS / (512*11);
UpDateSText(SBRPort, (UBYTE) LTR);
}
if (ReadSBlock(SearchIO, ROS / 512, 2, tdb)) puts("error");
virtbuf = &tdb[OS - ROS];
for (j = 0; (j < 512-n) && !eq; j++)
{
eq = (*MatchF[m])(&virtbuf[j], s, n);
}
if (!eq) OS += 512 - n;
if (imsg = GT_GetIMsg(SBWindow->UserPort))
{
GT_ReplyIMsg(imsg);
stop = TRUE;
}
}
MotorOff(SearchIO);
CloseTDIO(SearchIO);
FreeMem(tdb, 2*512L);
CloseWindow(SBWindow);
FreeGadgets(glist);
if (eq) return((OS + j - 1) | 0x80000000);
else return(0L);
}
}
void ShowDataFound(offset, type)
ULONG offset;
UBYTE type;
{
ULONG K;
offset &= 0x7fffffff;
ReadBlocks(drive, offset / 512, 1, BB);
if (type == sf_Number) CursorX = (offset & 0x0000000f)*2;
else CursorX = (offset & 0x0000000f) + 32;
RealCursorY = (offset & 0x000001f0) / 16;
if (RealCursorY < 16)
{
K = 0L;
CursorY = RealCursorY;
}
else
{
K = 0xffff;
CursorY = RealCursorY - 16;
}
NewModifyProp(&SchuifGadget, Window, NULL,
Schuif_info.Flags, 0, (UWORD) K, 0,
Schuif_info.VertBody, 1);
UpDateSB();
Track_info.LongInt = offset / (512*11);
Sector_info.LongInt = (offset / 512) % 11;
Block_info.LongInt = offset / (512);
UpDateTrSeG();
UpDateBlockG();
sprintf(&SIText[16], " ");
sprintf(&FIText[6], "%d", (UBYTE) (offset / (512*11)));
if (type == sf_Number) ShowText2(Window, "Data Found at", FIText, NULL);
else ShowText2(Window, "String found at", FIText, NULL);
}
void SearchS()
{
struct SData SSData;
struct Requester *IB;
ULONG L = 0, K;
IB = BlockInput(Window);
OpenRequester(Window, &SSData, sf_NCS);
if (SSData.ByteCount > 0)
{
L = Search(&SSData, drive);
if (L) ShowDataFound(L, sf_Normal);
else ShowText2(Window, "String not found", "End of search", NULL);
}
UnBlockInput(IB, Window);
}
void SearchB()
{
struct SData NSData;
ULONG L = 0, K;
struct Requester *IB;
IB = BlockInput(Window);
OpenRequester(Window, &NSData, sf_Number);
if (NSData.ByteCount > 0)
{
if ((NSData.ByteCount = ProcessSString(NSData.SearchData)) > 0)
{
L = Search(&NSData, drive);
if (L) ShowDataFound(L, sf_Number);
else ShowText2(Window, "Data not found", "End of search", NULL);
}
else ShowText2(Window, "Error in search-input", NULL, NULL);
}
UnBlockInput(IB, Window);
}