FIFO-stream


Eine Delphi-Klassenimplementierung eines FIFO-Streams.
Ein Stream von FIFO (First In First Out) ist nützlich, wenn Sie müssen ständig Daten in einem Puffer Mitglied erhalten, wollen aber nicht, dass Speicherpuffer ständig wachsen.
Es wird normalerweise verwendet, wenn Sie einen Mp3-audio-Stream aus dem Internet empfangen. Möglicherweise müssen Sie halten, bis ein voller Mp3-Puffer empfangen wurde, aber will nicht Ihre Puffer weiter wachsen auf die volle Größe der Mp3 gestreamt wird.
Der Trick ist einen zirkulären Puffer implementiert, sobald Sie über das Ende des Puffers zu schreiben, die Ihre Position an den Anfang des Puffers zurückgesetzt wird. Das einzige Problem ist wirklich, das auftreten kann ist, dass Sie möglicherweise Daten schneller als Sie verarbeitet werden, was zu einem Pufferüberlauf. Es ist ratsam, in erster Linie den Puffer zu groß wird. Hier ist meine eigene Implementierung. Bitte entfernen Sie nicht den copyright-Hinweis.
< === SNIP === >
(C) Peter Morris - [email protected] / [email protected]
Einheit FIFOStream;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Klassen;
Typ
EFIFOStream = class(Exception);
TFIFOStream = class(TObject)
Private
FData: PChar;
FMemorySize: Integer;
FBufferEnd,
FBufferStart: Integer;
geschützt
öffentliche
Konstruktor Create(aSize: Integer); virtuellen;
Destruktor Destroy; außer Kraft setzen;
Funktion BufferReadSize: Integer;
Funktion BufferWriteSize: Integer;
Verfahrens Clear;
Verfahren Peek (const aBuffer: Zeiger; Anzahl: Integer);
Verfahren lesen (const aBuffer: Zeiger; Anzahl: Integer);
Prozedur schreiben (const aSource: Zeiger; Anzahl: Integer);
veröffentlicht
Ende;
Umsetzung
Procedure CharMove (const Quelle; Var Dest; Anzahl: Integer);
ASM
Hinweis: Wenn diese Funktion aufgerufen wird, übergibt Delphi die Parameter wie folgt
ECX = Count
EAX = Const Quelle
EDX = Var-Dest
Wenn keine zu kopierenden Bytes, gerade beendet insgesamt sinnlos drängen Register
CMP ECX, 0
Je @JustQuit
Bewahren Sie die kritischen Delphi-Register
Push ESI
Push EDI
Verschieben Sie Quellcode in ESI (in der Regel das Quellcode-Register)
Verschieben Sie Dest in EDI (im Allgemeinen die DEST-Register für Zeichenfolge-Befehle)
Dies kann nicht wirklich erforderlich sein, als ich bin nicht MOVsb etc.
Ich kann nur EAX und EDX verwenden können, besteht möglicherweise eine Strafe für
nicht mit ESI, EDI, aber ich bezweifle es, das ist eine andere Sache einen Versuch Wert!
MOV ESI, EAX
MOV EDI, EDX
Die folgende Schleife ist das gleiche wie RepNZ MovSB, aber seltsamerweise schneller!
Die @Loop:
Das Quellcode-Byte zu erhalten
MOV AL, [ESI]
Zeigen Sie auf das nächste byte
Inc ESI
Nimm sie auf die Dest
MOV [EDI], AL

Punkt-Dest zur nächsten position
Inc-EDI
Dec-ECX zu beachten, wie viele, die wir noch haben, um zu kopieren
Dec-ECX
Wenn ECX <> 0 wird loop
JNZ @Loop
Pop EDI
Pop ESI
Die @JustQuit:
Ende;

{TFIFOStream}
Funktion TFIFOStream.BufferReadSize: Integer;
beginnen
Wenn FBufferEnd > = FBufferStart then //Not geschlungen
Ergebnis: = FBufferEnd - FBufferStart
anderes //Looped
Ergebnis: = FMemorySize - FBufferStart + FBufferEnd;
Ende;
Funktion TFIFOStream.BufferWriteSize: Integer;
beginnen
Ergebnis: = FMemorySize - BufferReadSize;
Ende;
Prozedur TFIFOStream.Clear;
beginnen
FBufferEnd: = 0;
FBufferStart: = 0;
Ende;
Konstruktor TFIFOStream.Create(aSize: Integer);
beginnen
geerbte erstellen;
Wenn aSize < 1024 dann
EFIFOStream.Create erhöhen ('Puffergröße muß mindestens 1K.');
FMemorySize: = aSize;
GetMem (FData, FMemorySize);
FBufferStart: = 0;
FBufferEnd: = 0;
Ende;
Destruktor TFIFOStream.Destroy;
beginnen
FreeMem(FData);
erbte;
Ende;
Procedure TFIFOStream.Peek (const aBuffer: Zeiger; Anzahl: Integer);
var
OrigStart: Integer;
beginnen
OrigStart: = FBufferStart;
versuchen Sie
Lesen (aBuffer, Count);
Schließlich
FBufferStart: = OrigStart;
Ende;
Ende;
Procedure TFIFOStream.Read (const aBuffer: Zeiger; Anzahl: Integer);
var
Quelle,
Dest: PChar;
CopyLen: Integer;
beginnen
Quelle: = [FBufferStart];-@FData
Dest: = aBuffer;
Wenn BufferReadSize < dann zählen
Erhöhen der EFIFOStream.Create ('Buffer-Underrun.');
CopyLen: = FMemorySize - FBufferStart;
Wenn CopyLen > CopyLen dann zählen: = Count;
CharMove(Source^,Dest^,CopyLen);
Inc(FBufferStart,CopyLen);
Wenn geschlungen
Wenn FBufferStart > = FMemorySize, dann beginnen
FBufferStart: = FBufferStart - FMemorySize;
Read(@dest[CopyLen],count-CopyLen) aus;
Ende;
Ende;
Procedure TFIFOStream.Write (const aSource: Zeiger; Anzahl: Integer);
var
Quelle,
Dest: PChar;
CopyLen: Integer;
beginnen
Quelle: = aSource;
Dest: = [FBufferEnd];-@FData
Wenn BufferWriteSize < dann zählen
Auslösen von EFIFOStream.Create ('Puffer übermäßige ausführen.');
CopyLen: = FMemorySize - FBufferEnd;
Wenn CopyLen > CopyLen dann zählen: = Count;
CharMove(Source^,Dest^,CopyLen);
Inc(FBufferEnd,CopyLen);
Wenn geschlungen
Wenn FBufferEnd > = FMemorySize, dann beginnen
FBufferEnd: = FBufferEnd - FMemorySize;
Write(@Source[CopyLen],count-CopyLen) aus;
Ende;
Ende;
Ende.









FIFO-stream


FIFO-stream : Mehreren tausend Tipps, um Ihr Leben einfacher machen.


Eine Delphi-Klassenimplementierung eines FIFO-Streams.
Ein Stream von FIFO (First In First Out) ist nützlich, wenn Sie müssen ständig Daten in einem Puffer Mitglied erhalten, wollen aber nicht, dass Speicherpuffer ständig wachsen.
Es wird normalerweise verwendet, wenn Sie einen Mp3-audio-Stream aus dem Internet empfangen. Möglicherweise müssen Sie halten, bis ein voller Mp3-Puffer empfangen wurde, aber will nicht Ihre Puffer weiter wachsen auf die volle Größe der Mp3 gestreamt wird.
Der Trick ist einen zirkulären Puffer implementiert, sobald Sie über das Ende des Puffers zu schreiben, die Ihre Position an den Anfang des Puffers zurückgesetzt wird. Das einzige Problem ist wirklich, das auftreten kann ist, dass Sie möglicherweise Daten schneller als Sie verarbeitet werden, was zu einem Pufferüberlauf. Es ist ratsam, in erster Linie den Puffer zu groß wird. Hier ist meine eigene Implementierung. Bitte entfernen Sie nicht den copyright-Hinweis.
< === SNIP === >
(C) Peter Morris - [email protected] / [email protected]
Einheit FIFOStream;
Schnittstelle
verwendet
Windows, Nachrichten, SysUtils, Klassen;
Typ
EFIFOStream = class(Exception);
TFIFOStream = class(TObject)
Private
FData: PChar;
FMemorySize: Integer;
FBufferEnd,
FBufferStart: Integer;
geschützt
öffentliche
Konstruktor Create(aSize: Integer); virtuellen;
Destruktor Destroy; außer Kraft setzen;
Funktion BufferReadSize: Integer;
Funktion BufferWriteSize: Integer;
Verfahrens Clear;
Verfahren Peek (const aBuffer: Zeiger; Anzahl: Integer);
Verfahren lesen (const aBuffer: Zeiger; Anzahl: Integer);
Prozedur schreiben (const aSource: Zeiger; Anzahl: Integer);
veröffentlicht
Ende;
Umsetzung
Procedure CharMove (const Quelle; Var Dest; Anzahl: Integer);
ASM
Hinweis: Wenn diese Funktion aufgerufen wird, übergibt Delphi die Parameter wie folgt
ECX = Count
EAX = Const Quelle
EDX = Var-Dest
Wenn keine zu kopierenden Bytes, gerade beendet insgesamt sinnlos drängen Register
CMP ECX, 0
Je @JustQuit
Bewahren Sie die kritischen Delphi-Register
Push ESI
Push EDI
Verschieben Sie Quellcode in ESI (in der Regel das Quellcode-Register)
Verschieben Sie Dest in EDI (im Allgemeinen die DEST-Register für Zeichenfolge-Befehle)
Dies kann nicht wirklich erforderlich sein, als ich bin nicht MOVsb etc.
Ich kann nur EAX und EDX verwenden können, besteht möglicherweise eine Strafe für
nicht mit ESI, EDI, aber ich bezweifle es, das ist eine andere Sache einen Versuch Wert!
MOV ESI, EAX
MOV EDI, EDX
Die folgende Schleife ist das gleiche wie RepNZ MovSB, aber seltsamerweise schneller!
Die @Loop:
Das Quellcode-Byte zu erhalten
MOV AL, [ESI]
Zeigen Sie auf das nächste byte
Inc ESI
Nimm sie auf die Dest
MOV [EDI], AL

Punkt-Dest zur nächsten position
Inc-EDI
Dec-ECX zu beachten, wie viele, die wir noch haben, um zu kopieren
Dec-ECX
Wenn ECX <> 0 wird loop
JNZ @Loop
Pop EDI
Pop ESI
Die @JustQuit:
Ende;

{TFIFOStream}
Funktion TFIFOStream.BufferReadSize: Integer;
beginnen
Wenn FBufferEnd > = FBufferStart then //Not geschlungen
Ergebnis: = FBufferEnd - FBufferStart
anderes //Looped
Ergebnis: = FMemorySize - FBufferStart + FBufferEnd;
Ende;
Funktion TFIFOStream.BufferWriteSize: Integer;
beginnen
Ergebnis: = FMemorySize - BufferReadSize;
Ende;
Prozedur TFIFOStream.Clear;
beginnen
FBufferEnd: = 0;
FBufferStart: = 0;
Ende;
Konstruktor TFIFOStream.Create(aSize: Integer);
beginnen
geerbte erstellen;
Wenn aSize < 1024 dann
EFIFOStream.Create erhöhen ('Puffergröße muß mindestens 1K.');
FMemorySize: = aSize;
GetMem (FData, FMemorySize);
FBufferStart: = 0;
FBufferEnd: = 0;
Ende;
Destruktor TFIFOStream.Destroy;
beginnen
FreeMem(FData);
erbte;
Ende;
Procedure TFIFOStream.Peek (const aBuffer: Zeiger; Anzahl: Integer);
var
OrigStart: Integer;
beginnen
OrigStart: = FBufferStart;
versuchen Sie
Lesen (aBuffer, Count);
Schließlich
FBufferStart: = OrigStart;
Ende;
Ende;
Procedure TFIFOStream.Read (const aBuffer: Zeiger; Anzahl: Integer);
var
Quelle,
Dest: PChar;
CopyLen: Integer;
beginnen
Quelle: = [FBufferStart];-@FData
Dest: = aBuffer;
Wenn BufferReadSize < dann zählen
Erhöhen der EFIFOStream.Create ('Buffer-Underrun.');
CopyLen: = FMemorySize - FBufferStart;
Wenn CopyLen > CopyLen dann zählen: = Count;
CharMove(Source^,Dest^,CopyLen);
Inc(FBufferStart,CopyLen);
Wenn geschlungen
Wenn FBufferStart > = FMemorySize, dann beginnen
FBufferStart: = FBufferStart - FMemorySize;
Read(@dest[CopyLen],count-CopyLen) aus;
Ende;
Ende;
Procedure TFIFOStream.Write (const aSource: Zeiger; Anzahl: Integer);
var
Quelle,
Dest: PChar;
CopyLen: Integer;
beginnen
Quelle: = aSource;
Dest: = [FBufferEnd];-@FData
Wenn BufferWriteSize < dann zählen
Auslösen von EFIFOStream.Create ('Puffer übermäßige ausführen.');
CopyLen: = FMemorySize - FBufferEnd;
Wenn CopyLen > CopyLen dann zählen: = Count;
CharMove(Source^,Dest^,CopyLen);
Inc(FBufferEnd,CopyLen);
Wenn geschlungen
Wenn FBufferEnd > = FMemorySize, dann beginnen
FBufferEnd: = FBufferEnd - FMemorySize;
Write(@Source[CopyLen],count-CopyLen) aus;
Ende;
Ende;
Ende.


FIFO-stream

FIFO-stream : Mehreren tausend Tipps, um Ihr Leben einfacher machen.
FIFO-stream
Wiezutun
Freunden empfehlen
  • gplus
  • pinterest

Kommentar

Einen Kommentar hinterlassen

Wertung