![]() |
Virtual Memory Stream
Liste der Anhänge anzeigen (Anzahl: 2)
Tachchen,
ich weiß nicht, ob es irgendwo schon etwas Gleichartiges gibt, aber da ich nichts fand [add](vergessen, daß es hier was kleines gab)[/add] und sowas brauchte, ist Dieses entstanden. Nun hab ich's halt auch mal aus meinem Projekt ausgebaut und da isses. :-D Hier erstmal der wichtigste Header: (ist nicht viel, aber so viel braucht man ja auch nicht)
Delphi-Quellcode:
Es handelt sich im Prinzip um eine Art MemoryStream, welcher allerdings keine eigene Speicherverwaltung besitzt.
TVMSState = (msNone, msCopy, msCopyAndFreeMem, msOnlyFree);
TVMSOnResize = Procedure(Sender: TVirtualMemoryStream; RequiredSize: LongInt; Var Memory: Pointer; Var MaxSize: LongInt; Var State: TVMSState) of Object; TVirtualMemoryStream = Class(TStream) Private FMemory: Pointer; FMaxSize, FSize: LongInt; FPosition: LongInt; FOnResize: TVMSOnResize; FTemp: Record P: Pointer; I: LongInt; S: TVMSState; O: TVMSOnResize; End; Procedure OnChangeMemory(Sender: TVirtualMemoryStream; RequiredSize: LongInt; Var Memory: Pointer; Var MaxSize: LongInt; Var State: TVMSState); Protected Function GetSize: Int64; Override; Procedure SetSize(NewSize: LongInt); Overload; Override; Procedure SetSize(Const NewSize: Int64); Overload; Override; Procedure SetMem(Memory: Pointer; MaxSize: LongInt); Virtual; Public Constructor Create(Memory: Pointer; MaxSize: LongInt; Size: LongInt = 0); Destructor Destroy; Override; Function Read (Var Buffer; Count: LongInt): LongInt; Override; Function Write(Const Buffer; Count: LongInt): LongInt; Override; Function Seek (Offset: LongInt; Origin: Word): LongInt; Overload; Override; Function Seek (Const Offset: Int64; Origin: TSeekOrigin): Int64; Overload; Override; Procedure SetPointer (Memory: Pointer; MaxSize: LongInt; Size: LongInt = 0); Function ChangeMemory(NewMemory: Pointer; NewMaxSize: LongInt; OldMemState: TVMSState = msCopyAndFreeMem): Pointer{old Memory}; Property Memory: Pointer Read FMemory; Property MaxSize: LongInt Read FMaxSize; Property OnResize: TVMSOnResize Read FOnResize Write FOnResize; End; TStaticMemoryStream wird beim Erstellen ein Speicherbereich und dessen Größe mitgegeben und nun kann man auf diesen Speicher über den Stream zugreifen. Ist dem OnResize-Ereignis etwas zugewiesen, macht die Klasse Selbe, allerdings kann hier der Speicher nachträglich getauscht, bzw in dessen Größe verändert werden. So kann man den Stream mit jeder Art von Speicherstrukturen versorgen und diese sogar dynamisch ändern lassen, wenn es nötig ist. Tja, und nun noch ein kleines Beispielprojektchen.
Delphi-Quellcode:
Ich glaub der Speicher-Callback war nicht sonderlich gut geglückt und ich werde ihn wohl noch auftrennen (quasi in Callbacks für Get, Free und Realoc).
Program Project1;
Uses Classes, Dialogs, StatMemStream; Var Data: Array[0..1023] of Byte; Stream: TStream; I: LongInt; S: AnsiString; Begin Move(PAnsiChar('Das ist ein ')^, Data, 12); Stream := TStaticMemoryStream.Create(@Data, SizeOf(Data), 12); Stream.Position := 12; i := $74736554; Stream.WriteBuffer(i, 4); i := $002E; Stream.WriteBuffer(i, 2); Stream.Position := 0; SetLength(S, Stream.Size); Stream.ReadBuffer(S[1], Length(S)); Stream.Free; ShowMessage(S); ShowMessage(PAnsiChar(@Data)); End. Der Stream ist natürlich nicht threadsicher (wie viele andere Streams auch), aber im Notfall kann man ja mehrere Streams auf den selben Speicher zeigen lassen. [edit] - der OnResize-Callback wurde etwas geändert - die beiden Klassen wurden vereint - und die Property wurden in einer Custom-Klasse versteckt |
Re: Static Memory Stream
Hi,
Habs mir noch nicht angeguckt. Schau es mir vllt. mal morgen an (jetzt erstmal schlafen gehn^^), aber es gibt sowas schon: TVirtualStream: ![]() :mrgreen: |
Re: Static Memory Stream
ups, den virtuellen hab'sch ganz vergessen. :oops:
|
Re: Static Memory Stream
Du hast vergessen den originalen Constructor zu überschrieben, oder?
Was passiert wenn jemand diesen aufruft? Deine privaten Variablen bleiben uninitialisiert und eine aussagekräftige Fehlermeldung kommt auch nicht. Die Fehler kommen erst wenn man später auf die jeweiligen Methoden zugreift. [Edit] Ich nehme meine Aussage zurück. Ich habe gerade bei TFileStream geschaut und da ist es genauso. Und wenn man versucht den Standardconstructor aufzurufen kommt ein Fehler das es keinen Constructor gibt der mit diesem übereinstimmt.
Delphi-Quellcode:
Das verwirrt mich allerdings denn letzendlich ist TFilestream über zig Umwege von TObject abgeleitet und dort existiert eben jener Constructor :gruebel: Warum funktioniert das also nicht?!
var
lStream: TFileStream; begin lStream := TFileStream.Create(); // = There is no overloaded Version of Create that can be called with these arguments |
Re: Static Memory Stream
Der Original-Constructor würde das Selbe machen, wie .Create(nil,0) .
Er verhält sich also wie ein leerer Stream, mit der Maximalgröße von 0. Eine unbeabsichtigte Zugriffsverletzung/Fehler sollte nicht auftreten, denn immerhin werden die Felder mit 0 initialisiert. Die einzigen Fehler, welche auftreten können, wären - ein ungültiger Pointer - MaxSize größer als der Speicherblock Ich könnte zwar prüfen ob der Speicherblock lesbar/schreibbar ist, aber da ich nicht sicherstellen kann, daß der Speicherblock wirklich für diesen Zugriff gedacht ist, hab ich diesbezüglich keine Prüfung verbaut. |
Re: Static Memory Stream
Stimmt. Ich bin derzeit insgesamt wohl etwas verwirrt :duck:
|
Re: Virtual Memory Stream
Ups, jetzt hätt ich beinah vergessen zu antworten.
@Bärchen: macht ja nix ![]() Joar und was gibt es sonst noch. Hab's doch noch schnell etwas geändert und hab mir mal des Generals Klassen-Name gemopst. :oops: Aber Aufgrund der besseren Bereichsprüfung laß ich meinen Code dennoch hier. :mrgreen: |
Re: Virtual Memory Stream
Zitat:
Copyright, Urheberrecht und so! TVirtualStream™ ! :evil: :mrgreen: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz