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 >
C/C++ Source or Header  |  1993-07-16  |  14KB  |  554 lines

  1.  
  2. /* Search.c  routines for searching data and strings on disk */
  3.  
  4. #include <exec/memory.h>
  5. #include <intuition/intuition.h>
  6. #include <libraries/gadtools.h>
  7. #include <clib/intuition_protos.h>
  8. #include <clib/gadtools_protos.h>
  9.  
  10. struct SData
  11. {
  12.    UWORD FirstTrack, LastTrack;
  13.    UBYTE SType;
  14.    UBYTE ByteCount;
  15.    UBYTE SearchData[40];
  16. };
  17.  
  18. struct Requester *BlockInput();
  19.  
  20. extern struct Window *Window;
  21. extern struct Gadget SchuifGadget;
  22. extern struct PropInfo Schuif_info;
  23. extern struct StringInfo Block_info, Track_info, Sector_info;
  24. extern APTR My_VisualInfo;
  25. extern struct TextAttr Style;
  26. extern int drive;
  27. extern UBYTE *BB;
  28. extern UBYTE CursorX, CursorY, RealCursorY;
  29.  
  30. struct IOStdReq *OpenTDIO();
  31.  
  32. char *MethodsTxt[] =
  33. {  "A = a", "A <> a", "Relative", NULL };
  34.  
  35. /* Search-modes */
  36. #define sf_NCS    0
  37. #define sf_Normal 1
  38. #define sf_Rel    2
  39. #define sf_Number 3
  40. #define sf_total  4
  41.  
  42. /* Gadget Id's */
  43. #define S_Method 11
  44. #define S_Cancel 12
  45. #define S_String 13
  46. #define S_FTrack 14
  47. #define S_LTrack 15
  48. #define S_Start  16
  49. #define S_Stop   21
  50.  
  51. UBYTE SIText[] = "Searching Track    ", FIText[] = "Track    ";
  52. struct IntuiText SearchText = {  1, 0, JAM2, 0, 0, &Style, SIText, NULL  };
  53.  
  54. struct NewGadget
  55. SFTrackNG = {  32, 44, 44, 13, "Start track", &Style, S_FTrack, PLACETEXT_BELOW,
  56.    NULL, NULL },
  57. SLTrackNG = {  136, 44, 44, 13, "End track", &Style, S_LTrack, PLACETEXT_BELOW,
  58.    NULL, NULL },
  59. SStringNG = {  12, 16, 180, 13, "String", &Style, S_String, PLACETEXT_BELOW,
  60.    NULL, NULL },
  61. SMethodNG = {  72, 76, 92, 12, "Case", &Style, S_Method, 0, NULL, NULL },
  62. SCancelNG = {  124, 94, 60, 12, "Cancel", &Style, S_Cancel, 0, NULL, NULL },
  63. SStartNG  = {  20, 94, 60, 12, "Start", &Style, S_Start, 0, NULL, NULL },
  64. SStopNG   = {  46, 52, 108, 12, "Abort Search", &Style, S_Stop, 0, NULL, NULL };
  65.  
  66. void DoStringGad(gad, window, data)
  67. struct Gadget *gad;
  68. struct Window *window;
  69. struct SData *data;
  70. {
  71.    struct StringInfo *SI;
  72.    int i;
  73.  
  74.    SI = (struct StringInfo *) gad->SpecialInfo;
  75.    for (i = 0; SI->Buffer[i] != 0; i++)
  76.       data->SearchData[i] = SI->Buffer[i];
  77.    data->SearchData[i] = 0;
  78.    data->ByteCount = i;
  79. }
  80.  
  81. void DoFTrackGad(gad, window, data)
  82. struct Gadget *gad;
  83. struct Window *window;
  84. struct SData *data;
  85. {
  86.    struct StringInfo *SI;
  87.    UBYTE track;
  88.  
  89.    SI = (struct StringInfo *) gad->SpecialInfo;
  90.    track = (UBYTE) SI->LongInt;
  91.    if ((track < 0) || (track > data->LastTrack))
  92.    {
  93.       track = data->FirstTrack;
  94.       sprintf(SI->Buffer, "%d\x00", data->FirstTrack);
  95.       SI->LongInt = track;
  96.       RefreshGList(gad, window, NULL, 1);
  97.    }
  98.    else data->FirstTrack = track;
  99. }
  100.  
  101. void DoLTrackGad(gad, window, data)
  102. struct Gadget *gad;
  103. struct Window *window;
  104. struct SData *data;
  105. {
  106.    struct StringInfo *SI;
  107.    UBYTE track;
  108.  
  109.    SI = (struct StringInfo *) gad->SpecialInfo;
  110.    track = (UBYTE) SI->LongInt;
  111.    if ((track < 0) || (track > 159) ||
  112.       (track < data->FirstTrack))
  113.    {
  114.       track = data->LastTrack;
  115.       sprintf(SI->Buffer, "%d\x00", track);
  116.       SI->LongInt = track;
  117.       RefreshGList(gad, window, NULL, 1);
  118.    }
  119.    else data->LastTrack = track;
  120. }
  121.  
  122. void OpenRequester(window, data, mode)
  123. struct Window *window;
  124. struct SData *data;
  125. UBYTE mode;
  126. {
  127.    BOOL terminated = FALSE;
  128.    struct Window *SWindow;
  129.    struct IntuiMessage *imsg;
  130.    struct Gadget *gad, *glist = NULL;
  131.    struct Gadget *FTR_gad, *LTR_gad, *SS_gad;
  132.    int i;
  133.    UBYTE *title;
  134.  
  135.    data->ByteCount = 0;
  136.    data->FirstTrack = 0;
  137.    data->LastTrack = 159;
  138.    data->SType = mode;
  139.  
  140.    SStartNG.ng_VisualInfo = My_VisualInfo;
  141.    SCancelNG.ng_VisualInfo = My_VisualInfo;
  142.    SMethodNG.ng_VisualInfo = My_VisualInfo;
  143.    SStringNG.ng_VisualInfo = My_VisualInfo;
  144.    SFTrackNG.ng_VisualInfo = My_VisualInfo;
  145.    SLTrackNG.ng_VisualInfo = My_VisualInfo;
  146.  
  147.    gad = CreateContext(&glist);
  148.    if (mode != sf_Number) gad = CreateGadget(CYCLE_KIND, gad, &SMethodNG,
  149.       GTCY_Labels, MethodsTxt, GTCY_Active, mode, TAG_END);
  150.    gad = CreateGadget(BUTTON_KIND, gad, &SStartNG, TAG_END);
  151.    gad = CreateGadget(BUTTON_KIND, gad, &SCancelNG, TAG_END);
  152.    SS_gad = gad = CreateGadget(STRING_KIND, gad, &SStringNG,
  153.       GTST_String, NULL, GTST_MaxChars, 20L, TAG_END);
  154.    gad->Activation |= GACT_STRINGCENTER;
  155.    FTR_gad = gad = CreateGadget(INTEGER_KIND, gad, &SFTrackNG,
  156.       GTIN_Number, 0L, GTIN_MaxChars, 3L, TAG_END);
  157.    gad->Activation |= GACT_STRINGCENTER;
  158.    LTR_gad = gad = CreateGadget(INTEGER_KIND, gad, &SLTrackNG,
  159.       GTIN_Number, 159L, GTIN_MaxChars, 3L, TAG_END);
  160.    gad->Activation |= GACT_STRINGCENTER;
  161.  
  162.    if (mode == sf_Number) title = "Search number";
  163.    else title = "Search string";
  164.  
  165.    SWindow = OpenWindowTags(NULL,
  166.       WA_Title,     title,
  167.       WA_Gadgets,   glist,      WA_AutoAdjust,    TRUE,
  168.       WA_Top,          40,      WA_Left,           180,
  169.       WA_Width,       204,      WA_InnerHeight,    100,
  170.       WA_DragBar,    TRUE,      WA_DepthGadget,   TRUE,
  171.       WA_Activate,   TRUE,
  172.       WA_IDCMP, CYCLEIDCMP | BUTTONIDCMP | STRINGIDCMP,
  173.       TAG_END);
  174.  
  175.    if (SWindow)
  176.    {
  177.       ActivateGadget(SS_gad, SWindow, NULL);
  178.       while (!terminated)
  179.       {
  180.          Wait (1 << SWindow->UserPort->mp_SigBit);
  181.          while ((!terminated) && (imsg =  GT_GetIMsg(SWindow->UserPort)))
  182.          {
  183.             switch (imsg->Class)
  184.             {
  185.                case IDCMP_GADGETUP:
  186.                   gad = (struct Gadget *)imsg->IAddress;
  187.                   switch(gad->GadgetID)
  188.                   {
  189.                      case S_Start:
  190.                         DoStringGad(SS_gad, SWindow, data);
  191.                         DoFTrackGad(FTR_gad, SWindow, data);
  192.                         DoLTrackGad(LTR_gad, SWindow, data);
  193.                         terminated = TRUE;
  194.                      break;
  195.  
  196.                      case S_Cancel:
  197.                         data->ByteCount = 0;
  198.                         terminated = TRUE;
  199.                      break;
  200.  
  201.                      case S_Method:
  202.                         data->SType = imsg->Code;
  203.                      break;
  204.  
  205.                      case S_FTrack:
  206.                         DoFTrackGad(gad, SWindow, data);
  207.                      break;
  208.  
  209.                      case S_LTrack:
  210.                         DoLTrackGad(gad, SWindow, data);
  211.                      break;
  212.                   }
  213.                break;
  214.             }
  215.          GT_ReplyIMsg(imsg);
  216.          }
  217.       }
  218.       CloseWindow(SWindow);
  219.    }
  220.    FreeGadgets(glist);
  221. }
  222.  
  223. BOOL Digit(ch)
  224. UBYTE ch;
  225. {
  226.    return((ch >= '0') && (ch <= '9'));
  227. }
  228.  
  229. BOOL ABCDEF(ch)
  230. UBYTE ch;
  231. {
  232.    return(((ch >= 'a') && (ch <= 'f')) || ((ch >= 'A') && (ch <= 'Z')));
  233. }
  234.  
  235. BOOL HexDigit(ch)
  236. UBYTE ch;
  237. {
  238.    return(Digit(ch) || ABCDEF(ch));
  239. }
  240.  
  241. UBYTE HexVal(digit)
  242. UBYTE digit;
  243. {
  244.    if (Digit(digit)) return(digit - '0');
  245.    else return(10 + ((digit - 'a') & 0x0f));
  246. }
  247.  
  248. UBYTE ComposeByte(dig1, dig2)
  249. UBYTE dig1, dig2;
  250. {
  251.    UBYTE rb;
  252.  
  253.    return(16*HexVal(dig1) + HexVal(dig2));
  254. }
  255.  
  256. int ProcessSString(string)
  257. UBYTE *string;
  258. {
  259.    UBYTE dstring[40];
  260.    int i, j, k;
  261.    ULONG UL;
  262.    BOOL ok = TRUE, error = FALSE;
  263.  
  264.    for (i = 0; string[i] != 0; i++) dstring[i] = string[i];
  265.    dstring[i] = 0;
  266.    i = 0;
  267.    j = 0;
  268.    while (ok && !error)
  269.    {
  270.       while (dstring[i] == ' ') i++;
  271.       if (dstring[i] == '$')
  272.       {
  273.          i++;
  274.          for (k = 0; HexDigit(dstring[i+k]); k++);
  275.          if (k == 0) error = TRUE;
  276.          else while (k > 0)
  277.          {
  278.  
  279.             if (k % 2)
  280.             {
  281.                string[j] = ComposeByte('0', dstring[i++]);
  282.                k--;
  283.             }
  284.             else
  285.             {
  286.                string[j] = ComposeByte(dstring[i], dstring[i+1]);
  287.                i += 2;
  288.                k -= 2;
  289.             }
  290.             j++;
  291.          }
  292.       }
  293.       else if (Digit(dstring[i]))
  294.       {
  295.          for (k = 0; Digit(dstring[i+k]); k++);
  296.          if (k > 10) error = TRUE;
  297.          else
  298.          {
  299.             UL = 0;
  300.             while (Digit(dstring[i])) UL = 10*UL + dstring[i++] - '0';
  301.             if (UL < 256) string[j++] = (UBYTE) UL;
  302.             else if (UL < 65536)
  303.             {
  304.                string[j++] = (UBYTE) (UL / 256);
  305.                string[j++] = (UBYTE) (UL & 0xff);
  306.             }
  307.             else
  308.             {
  309.                string[j++] = (UBYTE) (UL / 16777216);
  310.                string[j++] = (UBYTE) (UL / 65536);
  311.                string[j++] = (UBYTE) (UL / 256);
  312.                string[j++] = (UBYTE) (UL & 0xff);
  313.             }
  314.          }
  315.       }
  316.       else if (dstring[i] == '\'')
  317.       {
  318.          i++;
  319.          while (dstring[i] != '\'') string[j++] = dstring[i++];
  320.          i++;
  321.       }
  322.       else if (dstring[i] == 0) ok = FALSE;
  323.       else error = TRUE;
  324.    }
  325.    string[j] = 0;
  326.    if (error) j = 0;
  327.    return(j);
  328. }
  329.  
  330. void UpDateSText(rport, track)
  331. struct RastPort *rport;
  332. UBYTE track;
  333. {
  334.    sprintf(&SIText[16], "   ");
  335.    sprintf(&SIText[16], "%d", track);
  336.    PrintIText(rport, &SearchText, (200-IntuiTextLength(&SearchText))/2L, 20L);
  337. }
  338.  
  339. BOOL Match(string1, string2, n)
  340. UBYTE *string1, *string2;
  341. int n;
  342. {
  343.    int i;
  344.    BOOL rc;
  345.  
  346.    rc = TRUE;
  347.    i = 0;
  348.    while (rc && (i < n))
  349.    {
  350.       rc &= (string1[i] == string2[i]);
  351.       i++;
  352.    }
  353.    return(rc);
  354. }
  355.  
  356. UBYTE UpCase(ch)
  357. UBYTE ch;
  358. {
  359.    if ((ch >= 'a') && (ch <= 'z')) return(ch - 'a' + 'A');
  360.    else return(ch);
  361. }
  362.  
  363. BOOL MatchNCS(string1, string2, n)
  364. UBYTE *string1, *string2;
  365. int n;
  366. {
  367.    int i;
  368.    BOOL rc;
  369.  
  370.    rc = TRUE;
  371.    i = 0;
  372.    while (rc && (i < n))
  373.    {
  374.       rc &= (UpCase(string1[i]) == UpCase(string2[i]));
  375.       i++;
  376.    }
  377.    return(rc);
  378. }
  379.  
  380. BOOL MatchRel(string1, string2, n)
  381. BYTE *string1, *string2;
  382. int n;
  383. {
  384.    int i;
  385.    BYTE os;
  386.    BOOL rc;
  387.  
  388.    rc = TRUE;
  389.    os = string1[0] - string2[0];
  390.    i = 1;
  391.    while ((i < n) && rc)
  392.    {
  393.       rc &= (string1[i] - string2[i] == os);
  394.       i++;
  395.    }
  396.    return(rc);
  397. }
  398.  
  399. ULONG Search(data, drive, type)
  400. struct SData *data;
  401. int drive;
  402. {
  403.    int j, n, m;
  404.    ULONG SE, OS, ROS, LTR;
  405.    BOOL eq, stop;
  406.    UBYTE *s, *tdb, *virtbuf;
  407.    struct Gadget *gad, *glist = NULL;
  408.    struct Window *SBWindow;
  409.    struct RastPort *SBRPort;
  410.    struct IntuiMessage *imsg;
  411.    BOOL (*MatchF[sf_total])();
  412.    struct IOStdReq *SearchIO;
  413.  
  414.    tdb = (UBYTE *) AllocMem(2*512L, MEMF_CHIP);
  415.    if (!tdb)
  416.    {
  417.       puts("Not enough memory!");
  418.       return(0);
  419.    }
  420.    else if ((SearchIO = OpenTDIO(drive)))
  421.    {
  422.       MatchF[sf_Normal] = Match;
  423.       MatchF[sf_NCS] = MatchNCS;
  424.       MatchF[sf_Rel] = MatchRel;
  425.       MatchF[sf_Number] = Match;
  426.  
  427.       SStopNG.ng_VisualInfo = My_VisualInfo;
  428.       gad = CreateContext(&glist);
  429.       gad = CreateGadget(BUTTON_KIND, gad, &SStopNG, TAG_END);
  430.       SBWindow = OpenWindowTags(NULL, WA_Title,     "Searching...",
  431.          WA_Gadgets,   glist,      WA_AutoAdjust,    TRUE,
  432.          WA_Top,          40,      WA_Left,           180,
  433.          WA_Width,       200,      WA_InnerHeight,     60,
  434.          WA_DragBar,    TRUE,      WA_DepthGadget,   TRUE,
  435.          WA_Activate,   TRUE,
  436.          WA_IDCMP, BUTTONIDCMP,    TAG_END);
  437.       SBRPort = SBWindow->RPort;
  438.  
  439.       n = data->ByteCount;
  440.       s = data->SearchData;
  441.       m = data->SType;
  442.       SE = 11*512L*(data->LastTrack + 1);
  443.       LTR = data->FirstTrack;
  444.       OS = 11*512L*LTR;
  445.       eq = FALSE;
  446.       stop = FALSE;
  447.       UpDateSText(SBRPort, (UBYTE) LTR);
  448.  
  449.       while ((OS < SE) && !eq && !stop)
  450.       {
  451.          ROS = OS & 0xfffffe00;
  452.          if (ROS / (512*11) > LTR)
  453.          {
  454.             LTR = ROS / (512*11);
  455.             UpDateSText(SBRPort, (UBYTE) LTR);
  456.          }
  457.          if (ReadSBlock(SearchIO, ROS / 512, 2, tdb)) puts("error");
  458.          virtbuf = &tdb[OS - ROS];
  459.          for (j = 0; (j < 512-n) && !eq; j++)
  460.          {
  461.             eq = (*MatchF[m])(&virtbuf[j], s, n);
  462.          }
  463.          if (!eq) OS += 512 - n;
  464.          if (imsg =  GT_GetIMsg(SBWindow->UserPort))
  465.          {
  466.             GT_ReplyIMsg(imsg);
  467.             stop = TRUE;
  468.          }
  469.       }
  470.       MotorOff(SearchIO);
  471.       CloseTDIO(SearchIO);
  472.       FreeMem(tdb, 2*512L);
  473.       CloseWindow(SBWindow);
  474.       FreeGadgets(glist);
  475.  
  476.       if (eq) return((OS + j - 1) | 0x80000000);
  477.       else return(0L);
  478.    }
  479. }
  480.  
  481. void ShowDataFound(offset, type)
  482. ULONG offset;
  483. UBYTE type;
  484. {
  485.    ULONG K;
  486.  
  487.    offset &= 0x7fffffff;
  488.    ReadBlocks(drive, offset / 512, 1, BB);
  489.    if (type == sf_Number) CursorX = (offset & 0x0000000f)*2;
  490.    else CursorX = (offset & 0x0000000f) + 32;
  491.    RealCursorY = (offset & 0x000001f0) / 16;
  492.    if (RealCursorY < 16)
  493.    {
  494.       K = 0L;
  495.       CursorY = RealCursorY;
  496.    }
  497.    else
  498.    {
  499.       K = 0xffff;
  500.       CursorY = RealCursorY - 16;
  501.    }
  502.    NewModifyProp(&SchuifGadget, Window, NULL,
  503.       Schuif_info.Flags, 0, (UWORD) K, 0,
  504.       Schuif_info.VertBody, 1);
  505.    UpDateSB();
  506.    Track_info.LongInt = offset / (512*11);
  507.    Sector_info.LongInt = (offset / 512) % 11;
  508.    Block_info.LongInt = offset / (512);
  509.    UpDateTrSeG();
  510.    UpDateBlockG();
  511.    sprintf(&SIText[16], "   ");
  512.    sprintf(&FIText[6], "%d", (UBYTE) (offset / (512*11)));
  513.    if (type == sf_Number) ShowText2(Window, "Data Found at", FIText, NULL);
  514.    else ShowText2(Window, "String found at", FIText, NULL);
  515. }
  516.  
  517. void SearchS()
  518. {
  519.    struct SData SSData;
  520.    struct Requester *IB;
  521.    ULONG L = 0, K;
  522.  
  523.    IB = BlockInput(Window);
  524.    OpenRequester(Window, &SSData, sf_NCS);
  525.    if (SSData.ByteCount > 0)
  526.    {
  527.       L = Search(&SSData, drive);
  528.       if (L) ShowDataFound(L, sf_Normal);
  529.       else ShowText2(Window, "String not found", "End of search", NULL);
  530.    }
  531.    UnBlockInput(IB, Window);
  532. }
  533.  
  534. void SearchB()
  535. {
  536.    struct SData NSData;
  537.    ULONG L = 0, K;
  538.    struct Requester *IB;
  539.  
  540.    IB = BlockInput(Window);
  541.    OpenRequester(Window, &NSData, sf_Number);
  542.    if (NSData.ByteCount > 0)
  543.    {
  544.       if ((NSData.ByteCount = ProcessSString(NSData.SearchData)) > 0)
  545.       {
  546.          L = Search(&NSData, drive);
  547.          if (L) ShowDataFound(L, sf_Number);
  548.          else ShowText2(Window, "Data not found", "End of search", NULL);
  549.       }
  550.       else ShowText2(Window, "Error in search-input", NULL, NULL);
  551.    }
  552.    UnBlockInput(IB, Window);
  553. }
  554.