home *** CD-ROM | disk | FTP | other *** search
- {$R-,A+,S-,I-}
- UNIT tempSTM;
-
- INTERFACE
-
- USES Dos,Objects;
-
- Const LASTDRIVE:Char='Z'; { Letztes zu prüfendes Laufwerk bei suche nach
- temporärem Speicherplatz auf der Platte }
- MediaEMS =1; { Media-Konstanten spezifizieren Auslagerungs-Medium}
- MediaXMS =2;
- MediaRDD =4;
- MediaHDD =8;
- MediaALL =15;
- MediaNone =0;
-
- Procedure GetLastDrive; { bestimmt LASTDRIVE aus DOS-Commandline }
- { Format: /LD=<x> z.B. /LD=F }
-
- TYPE
- PTMPStream = ^TTMPStream;
- TTMPStream = OBJECT (TStream)
- ActualSTM :PStream;
- RequestedSize :Longint;
- Extension :ExtStr;
- TempName :PathStr;
- ChainNext :PtmpStream;
- Media :Word; {benutztes Speichermedium}
- AllowedMedia :Word;
- CONSTRUCTOR Init(MinSize:Longint;Fileext:ExtStr);
- DESTRUCTOR Done; virtual;
- FUNCTION GetPos: Longint; virtual;
- FUNCTION GetSize: Longint; virtual;
- PROCEDURE Read(var Buf; Count: Word); virtual;
- PROCEDURE Seek(Pos: Longint); virtual;
- PROCEDURE Truncate; virtual;
- PROCEDURE Write(var Buf; Count: Word); virtual;
- PROCEDURE Origin;
- Procedure Push(var Buf; Count: Word);
- Procedure Pop(var Buf; Count: Word);
- END;
-
-
- IMPLEMENTATION
- {$IFDEF DPMI}
- USES EMS,StrTool;
- {$ELSE}
- USES Xms,EMS,XMSStm,StrTool;
- {$ENDIF}
-
- Const EMS_SIZE:Longint=0;
- XMS_Size:Longint=0;
- HDD_Size:Longint=0;
- RDD_Size:Longint=0;
- RAM_path:PathStr='';
- TMP_Path:PathStr='';
- NextStm :PTMPStream=nil;
-
- function DriveValid(Drive: Char): Boolean; assembler;
- asm
- MOV DL,Drive
- MOV AH,36H
- SUB DL,'A'-1
- INT 21H
- INC AX
- JE @@2
- @@1: MOV AL,1
- @@2:
- end;
-
- Function GetTMPPath:Boolean;
- Var C,Drive:Char;
- MaxDiskSpace,
- Avail :Longint;
- SR :SearchRec;
- Const AlreadyCalled:Boolean=false;
- begin
- GetTMPpath:=true; { liefert immer true ! }
- If AlreadyCalled then Exit;
- AlreadyCalled:=true;
- MaxDiskSpace:=0;
- drive:=#0;
- For C:='C' to LASTDRIVE do
- begin
- If DriveValid(C) then
- begin
- Avail:=Diskfree(Ord(C)-64);
- FindFirst(C+':\*.*',VolumeID,SR);
- If (dosError=0) and
- ((Pos('VDISK',SR.Name)>0) or (Pos('RAM',SR.Name)>0)) then
- begin
- If RDD_Size=0 then
- begin
- RDD_Size:=Avail;
- RAM_Path:=C+':\';
- If tmp_path<>'' then Exit;
- end;
- end
- else
- begin
- If Avail>MaxDiskSpace then
- begin
- MaxDiskSpace:=Avail;
- Drive:=C;
- Tmp_path:=drive+':\';
- HDD_Size:=MaxDiskSpace;
- end;
- end;
- end else Exit;
- end;
- end;
-
- Function GetEMSsize:Longint;
- Var AV,Dummy :Word;
- begin
- EMMPageCount(AV,Dummy);
- GetEMSsize:=Longint(AV)*16384;
- end;
-
- Procedure GetRAM_Sizes;
- begin
- If Ram_path<>'' then
- RDD_Size:=DiskFree(Ord(Upcase(Ram_path[1]))-64);
- If TestEMMDriver then
- EMS_Size:=GetEMSsize;
- {$IFDEF DPMI}
- XMS_Size:=MaxAvail;
- {$ELSE}
- If XMS_DriverOk and (XMS_Result=XMSok) then
- XMS_Size:=Longint(XMS.MaxAVAIL)*1024 else XMS_Size:=0;
- {$ENDIF}
- end;
-
- Procedure GetDisk_Size;
- begin
- If tmp_path='' then Exit;
- HDD_Size:=DiskFree(Ord(Upcase(Tmp_path[1]))-64);
- end;
-
- Procedure EraseF(Var N:PathStr);
- Var F:File;
- T:Word;
- begin
- If N='' then Exit;
- Assign(F,N);
- {$I-}
- Erase(F);
- T:=Ioresult;
- {$I+}
- end;
-
- Function TMPSTM(Size :Longint;Ext:ExtStr;Var TName:String;Var Media:Word;Allowed:Word):Pstream;
- Var tmp :Pstream;
- begin
- tmp:=nil;
- Tname:='';
- If System.MaxAvail>1024 then
- begin
- GetRAM_Sizes;
- If (XMS_Size>=Size) and (Allowed and MediaXMS>0) then
- begin
- {$IFDEF DPMI}
- tmp:=New(PmemoryStream,Init(16384,16384));
- {$ELSE}
- tmp:=New(PXMSStream,Init);
- {$ENDIF}
- Media:=MediaXMS;
- end
- else If (EMS_Size>=Size) and (Allowed and MediaEMS>0) then
- begin
- tmp:=New(PEMSStream,Init(Size,Size*3 div 2));
- Media:=MediaEMS;
- end
- else If GetTMPPath and (RDD_Size>=Size) and (Allowed and MediaRDD>0) then
- begin
- tName:=RandomFileName(RAM_Path,Ext);
- tmp:=New(PDosStream,Init(tname,StCreate));
- Media:=MediaRDD;
- end
- else
- begin
- If GetTMPpath then GETDisk_Size;
- If (HDD_Size >=Size) then
- begin
- tName:=RandomFileName(TMP_Path,Ext);
- tmp:=New(PDosStream,Init(tname,StCreate));
- Media:=MediaHDD;
- end;
- end;
- end;
- If tmp<>nil then
- If tmp^.Status<>Stok then
- begin
- Dispose(tmp,done);
- tmp:=nil;
- EraseF(Tname);
- end;
- TMPSTM:=TMP;
- end;
-
- CONSTRUCTOR TTMPStream.Init;
- BEGIN
- Tstream.Init;
- ActualStm:=nil;
- RequestedSize:=MinSize;
- ChainNext:=NextStm;
- NextStm:=@self;
- AllowedMedia:=MediaAll;
- Extension :=FileExt;
- Repeat
- TempName:='';
- Status:=0;
- ActualStm:=TMPSTM(Minsize,Extension,TempName,Media,AllowedMedia);
- If ActualStm=nil then
- begin
- AllowedMedia:=AllowedMedia and Not(Media);
- Status := stInitError;
- end;
- Until (ActualStm<>nil) or (AllowedMedia=MediaNone);
- If ActualStm=nil then ErrorInfo := 0;
- If ActualStm<>nil then
- With ActualStm^ do Self.Error(Status,ErrorInfo);
- END;
-
- DESTRUCTOR TTMPStream.Done;
- Var tmp :PtmpStream;
- BEGIN
- If NextStm=@Self then
- NextStm:=Nextstm^.ChainNext
- else
- begin
- tmp:=NextStm;
- While tmp<>nil do
- begin
- If Tmp^.ChainNext=@self then
- begin
- Tmp^.ChainNext:=ChainNext; {Kettung für Exit-Proc freigeben}
- Tmp:=nil;
- end else tmp:=tmp^.ChainNext;
- end;
- end;
- If ActualStm<>nil then Dispose(ActualStm,Done);
- EraseF(Tempname);
- TStream.Done;
- END;
-
- FUNCTION TTMPStream.GetPos: Longint;
- BEGIN
- GetPos := ActualStm^.Getpos;
- END;
-
- FUNCTION TTMPStream.GetSize: Longint;
- BEGIN
- GetSize :=ActualStm^.GetSize;
- END;
-
- PROCEDURE TTMPStream.Read(var Buf; Count: Word);
- BEGIN
- ActualStm^.Read(Buf,Count);
- With ActualStm^ do Self.Error(Status,ErrorInfo);
- END;
-
- PROCEDURE TTMPStream.Seek(Pos: Longint);
- BEGIN
- ActualStm^.Seek(Pos);
- With ActualStm^ do Self.Error(Status,ErrorInfo);
- END;
-
- PROCEDURE TTMPStream.Truncate;
- BEGIN
- ActualStm^.Truncate;
- With ActualStm^ do Self.Error(Status,ErrorInfo);
- END;
-
- PROCEDURE TTMPStream.Write(var Buf; Count: Word);
- Var OldError :Word;
- OldInfo :Word;
- Temp :Pstream;
- NewSize :Longint;
- NewMedia :Word;
- tmpName :PathStr;
- Ok :Boolean;
- BEGIN
- With ActualStm^ Do
- begin
- OldError:=Status;
- Write(Buf,Count);
- If Status<>StOk then
- If OldError=StOk then
- If Media<>MediaHDD then
- begin
- OldInfo:=ErrorInfo;
- OldError:=Status;
- AllowedMedia:=AllowedMedia and Not(Media);
- Reset;
- Ok:=false;
- Repeat
- temp:=nil;
- tmpname:='';
- NewSize:=GetSize*3 div 2;
- If NewSize<RequestedSize then
- NewSize:=RequestedSize;
- temp:=TMPSTM(NewSize,Extension,tmpname,NewMedia,AllowedMedia);
- If temp=nil then AllowedMedia:=AllowedMedia and Not(NewMedia);
- Until (temp<>nil) or (AllowedMedia=MediaNone);
- If (temp<>nil) then
- begin
- Origin;
- temp^.CopyFrom(ActualStm^,ActualStm^.GetSize);
- If temp^.Status<>StOk then dispose(temp,Done)
- else
- begin
- dispose(ActualStm,done);
- ActualStm:=temp;
- RequestedSize:=NewSize;
- Media :=NewMedia;
- Ok:=true;
- tempname:=tmpname;
- temp^.Write(Buf,Count);
- end;
- end; {temp<>nil }
- If Not Ok then
- ActualStm^.Error(OldError,OldInfo);
- end;
- Self.Error(ActualStm^.Status,ActualStm^.ErrorInfo);
- end;
- END;
-
- PROCEDURE TTMPStream.Origin;
- begin
- ActualStm^.Flush;
- ActualStm^.Reset;
- ActualStm^.Seek(0);
- end;
-
- PROCEDURE TTMPStream.Push(var Buf; Count: Word);
- begin
- Write(Buf,Count);
- end;
-
- PROCEDURE TTMPStream.Pop(var Buf; Count: Word);
- Var Pos,
- ASize:Longint;
-
- begin
- ASize:=GetSize;
- Pos:=Asize-Count;
- If Pos<0 then
- begin
- count:=Asize;
- Pos:=0;
- end;
- Seek(Pos);
- Read(Buf,Count);
- Seek(Pos);
- Truncate;
- end;
-
- Var Pexitold:Pointer;
-
- Procedure MyExit; far;
- Var tmp:PtmpStream;
- begin
- While NextStm<>nil do
- begin
- tmp:=NextStm;
- NextStm:=NextStm^.ChainNext;
- tmp^.done;
- end;
- ExitProc:=PexitOld;
- end;
-
- Procedure GetLastDrive;
- Var tmp :PathStr;
- I,J :Word;
- Drive:Char;
- begin
- Drive:=#0;
- For I:=1 to ParamCount do
- begin
- tmp:=ParamStr(I);
- For J:=1 to Byte(tmp[0]) do tmp[J]:=Upcase(tmp[J]);
- If (Pos('/LD=',tmp)=1) and (tmp[0]>#5) then
- Drive:=TMP[5];
- end;
- If (Drive>='C') and (Drive<='Z') then LastDrive:=Drive;
- end;
-
- begin
- Pexitold:=ExitProc;
- ExitProc:=@MyExit;
- GetRam_Sizes;
- END.
-
-