Here's a few more optimizations to MKMSGFID.

All will speed up MSGStartup, and will fit either in the QuickMSGStartup2
(wich I've already sent to you) or in the original MSGSTARTUP.

One sees to it that you stop looking for kludges when all the interresting
info is found.

The second let's the programmer specify a maximum number of bytes to read
when looking for kludges.

The third let's the programmer specify the size of the filebuffer.
When scanning through lot's of mail for area and the like, but only reading
a few, a small buffer will be faster, especially if used together with
MaxKludgeSeek, when reading big mails, a big buffer will be larger.

The fourth sees to it the the fileobject only reads as many buffers as
necessary when starting up the message. This will make scanning a lot
faster, but might make reading a little bit slower. It also means that
I've added the ability to change buffersize to the FFileObj. One might
now initiate it with one buffersize, and the change it. It is impossible
to raise i higher that the initial size, and also to make it smaller than
the amount of characters in the buffer. This is still enough for  starting
up messages quicker. I specify it to 190 bytes in QuickMSGStartup1, 1024
bytes in QuickMsgStartup2 and set it to the standard (or userspecified)
size if after both of those.

I'll be writing you again. :-) I'd like to know what you think of these
suggestions, and the ones I've alreaddy sent you.


Unit  MKMSGFID:


Type FMsgType = Record
  ...
{ Added thsis}
  FoundFlags: byte;
  End;

{ If this is in the interface section, you don't have to be sure that
  you're working with a *.MSG base. You just specify
  MKMSGFid.MaxKludgeSeek:=n, if you want. If it is set to 0, no limit
  will be used. }
const MaxKludgeSeek  :  word  =  0;
{ Specifies size of filebuffer }
      FileBufSize: word = 4096;

{ Constants for use with FoundFlags }
const
    klFoundIntl  =  $01;
    klFoundTOPT  =  $02;
    klFoundFMPT  =  $04;
    klFoundAll   =  klFoundIntl+klFoundTOPT+klFoundFMPT;


Procedure FidoMsgObj.CheckZone(ZoneStr: String);
  Var
    DestZoneStr: String;
    Code: Word;

  Begin
  If (Upper(Copy(ZoneStr,1,4)) = 'INTL') Then
    Begin
    DestZoneStr := ExtractWord(ZoneStr, 2);
    DestZoneStr := StripBoth(DestZoneStr, ' ');
    DestZoneStr := Copy(DestZoneStr, 1, Pos(':', DestZoneStr) - 1);
    Val(DestZoneStr, FM^.Dest.Zone, Code);
    DestZoneStr := ExtractWord(ZoneStr,3);
    DestZoneStr := StripBoth(DestZoneStr, ' ');
    DestZoneStr := Copy(DestZoneStr, 1, Pos(':', DestZoneStr) - 1);
    Val(DestZoneStr, FM^.Orig.Zone, Code);
{ Set the FoundIntl flag }
    FoundFlags:=FoundFlags or klFoundIntl;
    End;
  End;


Procedure FidoMsgObj.CheckPoint(PointStr: String);
  Var
    DestPointStr: String;
    Code: Word;
    Temp: Word;

  Begin
  If (Upper(Copy(PointStr,1,4)) = 'TOPT') Then
    Begin
    DestPointStr := ExtractWord(PointStr, 2);
    DestPointStr := StripBoth(DestPointStr, ' ');
    Val(DestPointStr, Temp, Code);
    If Code = 0 Then
      FM^.Dest.Point := Temp;
{ Set the FoundTOPT flag }
    FoundFlags:=FoundFlags or klFoundTOPT;
    End;
  If (Upper(Copy(PointStr,1,4)) = 'FMPT') Then
    Begin
    DestPointStr := ExtractWord(PointStr, 2);
    DestPointStr := StripBoth(DestPointStr, ' ');
    Val(DestPointStr, Temp, Code);
    If Code = 0 Then
      FM^.Orig.Point := Temp;
{ Set the FoundFMPT flag }
    FoundFlags:=FoundFlags or klFoundFMPT;
    End;
  End;

Procedure FidoMsgObj.QuickMsgStartUp1;

  Begin
  If FM^.MsgOpen Then
    If FM^.MsgFile.CloseFile Then
      FM^.MsgOpen := False;
  If FM^.TmpOpen Then
    RemoveTmp;
{ Sets the file buffer to 190 bytes (size of header) }
  FM^.MsgFile.ChangeBufSize(190);
  LastSoft := False;
  If FileExist (FM^.NetMailPath + Long2Str(FM^.CurrMsg) + '.MSG') Then
    FM^.Error := 0
  Else
    FM^.Error := 200;
  If FM^.Error = 0 Then
    Begin
    If Not FM^.MsgFile.OpenFile(FM^.NetMailPath + Long2Str(FM^.CurrMsg) +
    '.Msg',  fmReadWrite + fmDenyNone) Then FM^.Error := 1000;
    End;
  If FM^.Error = 0 Then
    FM^.MsgOpen := True;
  FM^.MsgDone := False;
  FM^.MsgSize := FM^.MsgFile.RawSize;
  FM^.MsgEnd := 0;
  FM^.MsgStart := 190;
  FM^.Dest.Zone := FM^.DefaultZone;
  FM^.Dest.Point := 0;
  FM^.Orig.Zone := FM^.DefaultZone;
  FM^.Orig.Point := 0;
  FM^.Orig.Net := BufferWord(172);
  FM^.Orig.Node := BufferWord(168);
  FM^.Dest.Net := BufferWord(174);
  FM^.Dest.Node := BufferWord(166);
  FM^.TextCtr := FM^.MsgStart;
  If FM^.Error = 0 Then
    If Not CvtDate Then
      Begin
      FM^.QDate := '09-06-89';
      FM^.QTime := '19:76';
      End;
{ Restores the file buffer size }
  FM^.MsgFile.ChangeBufSize(FileBufSize);
  End;


Procedure FidoMsgObj.QuickMsgStartUp2;
  Var
    TStr: String;
    TmpChr: Char;
    NumRead: Word;
{ Added to keep track of read bytes }
    ReadBytes: word;

  Begin
  If FM^.Error = 0 Then
    Begin
{ Sets the file buffer size o 1024, should be enough when reading
  kludges. }
    FM^.MsgFile.ChangeBufSize(1024);
    TStr := GetString(128);
    CheckLine(TStr);
    if Length(TStr) > 0 Then
      Dec(FM^.TextCtr);
    If FM^.MsgFile.SeekFile(FM^.TextCtr) Then
      If FM^.MsgFile.BlkRead(TmpChr, 1, NumRead) Then;
{ Initialize read bytes and flags }
    ReadBytes:=1;
    FoundFlags:=0;
    While ((FM^.MsgEnd = 0) and (FM^.TextCtr <= FM^.MsgSize)) and
{ Check if Zones and points have alreaddy been found }
          (FoundFlags and klFoundAll<>klFoundAll) and not
{ Check if we've read the maximum number of bytes }
          ((MaxKludgeSeek>0) and (ReadBytes>MaxKludgeSeek)) do
      Begin
      Case TmpChr Of
        #0: FM^.MsgEnd := FM^.TextCtr;
        #13: Begin
          Inc(FM^.TextCtr);
          TStr := GetString(128);
          CheckLine(TStr);
          If Length(TStr) > 0 Then
            Dec(FM^.TextCtr);
          End;
        Else
          Begin
          Inc(FM^.TextCtr);
          If FM^.MsgFile.BlkRead(TmpChr, 1, NumRead) Then;
          inc(ReadBytes);
          End;
        End;
      End;
    If FM^.MsgEnd = 0 Then
      FM^.MsgEnd := FM^.MsgSize;
    FM^.MsgSize := FM^.MsgEnd;
    FM^.MsgStart := 190;
    FM^.TextCtr := FM^.MsgStart;
    FM^.MsgDone := False;
    LastSoft := False;
{ Restores filebuffer }
    FM^.MsgFile.ChangeBufSize(FileBufSize);
    End;
  End;

Constructor FidoMsgObj.Init;
  Begin
  New(FM);
  If FM = Nil Then
    Begin
    Fail;
    Exit;
    End;
  FM^.NetMailPath := '';
  FM^.TextCtr := 190;
  FM^.Dest.Zone := 0;
  FM^.Orig.Zone := 0;
  FM^.SeekOver := False;
  FM^.DefaultZone := 1;
{ Uses FileBufSize instead of fixed value }
  FM^.MsgFile.Init(FileBufSize);
  FM^.TmpOpen := False;
  FM^.MsgOpen := False;
  End;


Unit MKFFILE:


Type FFileObj = Object
  ...
  OrigSize: LongInt;         {Original size of buffer}
  Procedure  ChangeBufSize(BSize: LongInt);
    { Changes file buffer size "on the fly" }
  End;


Constructor FFileObj.Init(BSize: Word);
  Begin
  Buf := Nil;
  BufSize := BSize;
{ We must remember the original buffersize }
  OrigSize := BSize;
  BufStart := 0;           {Invalidate buffer}
  BufChars := 0;
  IsOpen := False;           {Initialize values}
  NeedWritten := False;
  CurrPos := 0;
  GetMem(Buf, BufSize);      {Allocate memory for buffer}
  If Buf = Nil Then
    Fail;
  End;


Destructor FFileObj.Done;
  Begin
  If IsOpen Then             {If file is open then close it}
    If CloseFile Then;
  If Buf <> Nil Then         {Free up memory}
{ Use original buffersize to be sure }
    FreeMem(Buf, OrigSize);
  End;


Procedure FFileObj.ChangeBufSize(BSize: LongInt);

  Begin
{ Cant't make the buffer smaller than the amount of characters in it. }
  If BSize<BufChars Then
    BSize := BufChars
  Else
{ Can't make it bigger than the initial (and allocated) size }
    If BSize>OrigSize Then
      BSize := OrigSize;
{ Change it. }
  BufSize := BSize;
  End;

