Fifo flux
Un Delphi classe de la mise en œuvre d'une FIFO flux.
UNE FIFO de flux (First In First Out) est utile lorsque vous avez besoin, en permanence, de recevoir des données à un membre de la mémoire tampon, mais vous ne voulez pas que la mémoire tampon à grandir sans cesse.
Il est généralement utilisé lors de la réception d'un flux audio Mp3 à partir d'Internet. Vous pourriez avoir besoin pour tenir jusqu'à ce que plein de Mp3 de la mémoire tampon a été reçue, mais ne voulez pas que votre tampon de continuer à grandir à la taille totale de la Mp3 diffusées en continu.
L'astuce est de mettre en œuvre un tampon circulaire, une fois que vous écrire après la fin de la mémoire tampon de votre position est remise à zéro au début de la mémoire tampon. Le seul problème qui peut se produire est que vous pouvez recevoir des données plus rapide que vous le processus, entraînant un dépassement de la mémoire tampon. Il est conseillé de faire le tampon trop grande dans la première place. Voici ma propre mise en œuvre. Merci de ne pas supprimer les avis de droit d'auteur.
<==========SNIP=========>
//(C) Peter Morris - [email protected] / [email protected]
unité de FIFOStream
interface
& nbsp & nbsp Windows, Messages, SysUtils, Classes
type
& nbsp & nbsp EFIFOStream = classe(Exception)
& nbsp & nbsp TFIFOStream = class(TObject)
& nbsp & nbsp privé
& ! & ! & ! & nbsp FData : PChar
& ! & ! & ! & nbsp FMemorySize : Integer
& ! & ! & ! & nbsp FBufferEnd,
& ! & ! & ! & nbsp FBufferStart : Entier
& nbsp & nbsp protégé
& nbsp & nbsp public
& ! & ! & ! & nbsp constructeur Créer(aSize : Integer) virtuel
& ! & ! & ! & nbsp destructeur de Détruire remplacer
& ! & ! & ! & nbsp fonction BufferReadSize : Integer
& ! & ! & ! & nbsp fonction BufferWriteSize : Entier
& ! & ! & ! & nbsp procédure Claire
& ! & ! & ! & nbsp procédure Peek(const aBuffer : Pointeur Count : Integer)
& ! & ! & ! & nbsp procédure de Lire(const aBuffer : Pointeur Count : Integer)
& ! & ! & ! & nbsp procédure Write(const aSource : Pointeur Count : Integer)
& nbsp & nbsp publié
& nbsp & nbsp fin
application
procédure CharMove(const Source var Dest Count : Integer)
asm
//Remarque: Lorsque cette fonction est appelée, delphi passe les paramètres comme suit
//ECX = Count
//EAX = Const Source
//EDX = Var Dest
& ! & ! & ! & ! & ! & ! & ! & nbsp //Si pas d'octets à copier, juste cesser de fumer, pas de point de pousser les registres
& ! & ! & ! & ! & ! & ! & ! & nbsp cmp ECX,0
& ! & ! & ! & ! & ! & ! & ! & nbsp Ej @JustQuit
& ! & ! & ! & ! & ! & ! & ! & nbsp //Préserver la critique delphi registres
& ! & ! & ! & ! & ! & ! & ! & nbsp push ESI
& ! & ! & ! & ! & ! & ! & ! & nbsp push EDI
& nbsp & ! & ! & ! & ! & ! & ! & nbsp //déplacer la Source ESI (généralement la SOURCE de registre)
& ! & ! & ! & ! & ! & ! & ! & nbsp //déplacer Dest en EDI (généralement le NOM du registre pour la chaîne de commandes)
& ! & ! & ! & ! & ! & ! & ! & nbsp //Cela peut ne pas être nécessaire, comme je ne suis pas à l'aide de MOVsb etc
& ! & ! & ! & ! & ! & ! & ! & nbsp //je pourrai peut-être juste utiliser EAX et EDX, il peut y avoir une pénalité pour
& ! & ! & ! & ! & ! & ! & ! & nbsp //ne pas utiliser d'ESI, EDI, mais j'en doute, c'est une autre chose qui vaut la peine d'essayer !
& ! & ! & ! & ! & ! & ! & ! & nbsp mov ESI, EAX
& ! & ! & ! & ! & ! & ! & ! & nbsp mov EDI, EDX
& ! & ! & ! & ! & ! & ! & ! & nbsp //La boucle suivante est la même que repNZ MovSB, mais bizarrement, plus rapide !
& ! & ! & ! & nbsp @Boucle:
& ! & ! & ! & ! & ! & ! & ! & nbsp //Obtenir la source de l'octet
& ! & ! & ! & ! & ! & ! & ! & nbsp Mov AL, [ESI]
& ! & ! & ! & ! & ! & ! & ! & nbsp //Point à l'octet suivant
& ! & ! & ! & ! & ! & ! & ! & nbsp Inc ESI
& ! & ! & ! & ! & ! & ! & ! & nbsp //Mettre dans la Dest
& ! & ! & ! & ! & ! & ! & ! & nbsp mov [EDI], AL
& ! & ! & ! & ! & ! & ! & ! & nbsp //dest Point à la position suivante
& ! & ! & ! & ! & ! & ! & ! & nbsp Inc EDI
& ! & ! & ! & ! & ! & ! & ! & nbsp //Dec ECX de noter combien nous avons de gauche à copier
& ! & ! & ! & ! & nbsp & nbsp & nbsp & nbsp Dec ECX
& ! & ! & ! & ! & ! & ! & ! & nbsp //Si ECX <> 0 alors la boucle
& ! & ! & ! & ! & ! & ! & ! & nbsp Jnz @Boucle
& ! & ! & ! & ! & ! & ! & ! & nbsp pop EDI
& ! & ! & ! & ! & ! & ! & nbsp & nbsp pop ESI
& ! & ! & ! & nbsp @JustQuit:
fin
{ TFIFOStream }
fonction de TFIFOStream.BufferReadSize: Integer
begin
& nbsp & nbsp si FBufferEnd >= FBufferStart alors //Pas de boucle
& ! & ! & ! & nbsp Résultat := FBufferEnd - FBufferStart
& nbsp & nbsp else //Boucle
& ! & ! & ! & nbsp Résultat := FMemorySize - FBufferStart FBufferEnd
fin
fonction de TFIFOStream.BufferWriteSize: Integer
begin
& nbsp & nbsp Résultat := FMemorySize - BufferReadSize
fin
procédure TFIFOStream.Clair
begin
& nbsp & nbsp FBufferEnd := 0
& nbsp & nbsp FBufferStart := 0
fin
constructeur TFIFOStream.Créer(aSize: Entier)
begin
& nbsp & nbsp hérité de Créer
// si l'aSize < 1024
// raise EFIFOStream.Create('taille de la mémoire Tampon doit être d'au moins 1K.')
& nbsp & nbsp FMemorySize := aSize
& nbsp & nbsp Getmem(FData, FMemorySize)
& nbsp & nbsp FBufferStart := 0
& nbsp & nbsp FBufferEnd := 0
fin
destructeur TFIFOStream.Détruire
begin
& nbsp & nbsp FreeMem(FData)
& nbsp & nbsp hérité
fin
procédure TFIFOStream.Peek(const aBuffer: Pointeur Count: Integer)
var
& nbsp & nbsp OrigStart : Integer
begin
& nbsp & nbsp OrigStart := FBufferStart
& nbsp & nbsp essayer
& ! & ! & ! & nbsp Lire(aBuffer, Comte)
& nbsp & nbsp enfin
& ! & ! & ! & nbsp FBufferStart := OrigStart
& nbsp & nbsp fin
fin
procédure TFIFOStream.Lire(const aBuffer : Pointeur Count: Integer)
var
& nbsp & nbsp Source,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Source := @FData[FBufferStart]
& nbsp & nbsp Dest := aBuffer
& nbsp & nbsp si BufferReadSize < Comte
& ! & ! & ! & nbsp élever EFIFOStream.Create('dépassement de mémoire Tampon.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferStart
& nbsp & nbsp si CopyLen > Comte CopyLen := Count
& nbsp & nbsp CharMove(Source^,B^,CopyLen)
& nbsp & nbsp Inc(FBufferStart,CopyLen)
& nbsp & nbsp //Si la boucle
& nbsp & nbsp si FBufferStart >= FMemorySize puis commencer
& ! & ! & ! & nbsp FBufferStart := FBufferStart - FMemorySize
& ! & ! & ! & nbsp Lire(@Dest[CopyLen],le Comte-CopyLen)
& nbsp & nbsp fin
fin
procédure TFIFOStream.Write(const aSource : Pointeur Count: Integer)
var
& nbsp & nbsp Source,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Source := aSource
& nbsp & nbsp Dest := @FData[FBufferEnd]
& nbsp & nbsp si BufferWriteSize < Comte
& ! & ! & ! & nbsp élever EFIFOStream.Create('Buffer over-run.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferEnd
& nbsp & nbsp si CopyLen > Comte CopyLen := Count
& nbsp & nbsp CharMove(Source^,B^,CopyLen)
& nbsp & nbsp Inc(FBufferEnd,CopyLen)
& nbsp & nbsp //Si la boucle
& nbsp & nbsp si FBufferEnd >= FMemorySize puis commencer
& ! & ! & ! & nbsp FBufferEnd := FBufferEnd - FMemorySize
& ! & ! & ! & nbsp Écrire(@Source[CopyLen],le Comte-CopyLen)
& nbsp & nbsp fin
fin
à la fin.
Fifo flux
Fifo flux : Plusieurs milliers de conseils pour vous faciliter la vie.
Un Delphi classe de la mise en œuvre d'une FIFO flux.
UNE FIFO de flux (First In First Out) est utile lorsque vous avez besoin, en permanence, de recevoir des donnees a un membre de la memoire tampon, mais vous ne voulez pas que la memoire tampon a grandir sans cesse.
Il est generalement utilise lors de la reception d'un flux audio Mp3 a partir d'Internet. Vous pourriez avoir besoin pour tenir jusqu'a ce que plein de Mp3 de la memoire tampon a ete reçue, mais ne voulez pas que votre tampon de continuer a grandir a la taille totale de la Mp3 diffusees en continu.
L'astuce est de mettre en œuvre un tampon circulaire, une fois que vous ecrire apres la fin de la memoire tampon de votre position est remise a zero au debut de la memoire tampon. Le seul probleme qui peut se produire est que vous pouvez recevoir des donnees plus rapide que vous le processus, entraînant un depassement de la memoire tampon. Il est conseille de faire le tampon trop grande dans la premiere place. Voici ma propre mise en œuvre. Merci de ne pas supprimer les avis de droit d'auteur.
<==========SNIP=========>
//(C) Peter Morris - [email protected] / [email protected]
unite de FIFOStream
interface
& nbsp & nbsp Windows, Messages, SysUtils, Classes
type
& nbsp & nbsp EFIFOStream = classe(Exception)
& nbsp & nbsp TFIFOStream = class(TObject)
& nbsp & nbsp prive
& ! & ! & ! & nbsp FData : PChar
& ! & ! & ! & nbsp FMemorySize : Integer
& ! & ! & ! & nbsp FBufferEnd,
& ! & ! & ! & nbsp FBufferStart : Entier
& nbsp & nbsp protege
& nbsp & nbsp public
& ! & ! & ! & nbsp constructeur Creer(aSize : Integer) virtuel
& ! & ! & ! & nbsp destructeur de Detruire remplacer
& ! & ! & ! & nbsp fonction BufferReadSize : Integer
& ! & ! & ! & nbsp fonction BufferWriteSize : Entier
& ! & ! & ! & nbsp procedure Claire
& ! & ! & ! & nbsp procedure Peek(const aBuffer : Pointeur Count : Integer)
& ! & ! & ! & nbsp procedure de Lire(const aBuffer : Pointeur Count : Integer)
& ! & ! & ! & nbsp procedure Write(const aSource : Pointeur Count : Integer)
& nbsp & nbsp publie
& nbsp & nbsp fin
application
procedure CharMove(const Source var Dest Count : Integer)
asm
//Remarque: Lorsque cette fonction est appelee, delphi passe les parametres comme suit
//ECX = Count
//EAX = Const Source
//EDX = Var Dest
& ! & ! & ! & ! & ! & ! & ! & nbsp //Si pas d'octets a copier, juste cesser de fumer, pas de point de pousser les registres
& ! & ! & ! & ! & ! & ! & ! & nbsp cmp ECX,0
& ! & ! & ! & ! & ! & ! & ! & nbsp Ej @JustQuit
& ! & ! & ! & ! & ! & ! & ! & nbsp //Preserver la critique delphi registres
& ! & ! & ! & ! & ! & ! & ! & nbsp push ESI
& ! & ! & ! & ! & ! & ! & ! & nbsp push EDI
& nbsp & ! & ! & ! & ! & ! & ! & nbsp //deplacer la Source ESI (generalement la SOURCE de registre)
& ! & ! & ! & ! & ! & ! & ! & nbsp //deplacer Dest en EDI (generalement le NOM du registre pour la chaîne de commandes)
& ! & ! & ! & ! & ! & ! & ! & nbsp //Cela peut ne pas etre necessaire, comme je ne suis pas a l'aide de MOVsb etc
& ! & ! & ! & ! & ! & ! & ! & nbsp //je pourrai peut-etre juste utiliser EAX et EDX, il peut y avoir une penalite pour
& ! & ! & ! & ! & ! & ! & ! & nbsp //ne pas utiliser d'ESI, EDI, mais j'en doute, c'est une autre chose qui vaut la peine d'essayer !
& ! & ! & ! & ! & ! & ! & ! & nbsp mov ESI, EAX
& ! & ! & ! & ! & ! & ! & ! & nbsp mov EDI, EDX
& ! & ! & ! & ! & ! & ! & ! & nbsp //La boucle suivante est la meme que repNZ MovSB, mais bizarrement, plus rapide !
& ! & ! & ! & nbsp @Boucle:
& ! & ! & ! & ! & ! & ! & ! & nbsp //Obtenir la source de l'octet
& ! & ! & ! & ! & ! & ! & ! & nbsp Mov AL, [ESI]
& ! & ! & ! & ! & ! & ! & ! & nbsp //Point a l'octet suivant
& ! & ! & ! & ! & ! & ! & ! & nbsp Inc ESI
& ! & ! & ! & ! & ! & ! & ! & nbsp //Mettre dans la Dest
& ! & ! & ! & ! & ! & ! & ! & nbsp mov [EDI], AL
& ! & ! & ! & ! & ! & ! & ! & nbsp //dest Point a la position suivante
& ! & ! & ! & ! & ! & ! & ! & nbsp Inc EDI
& ! & ! & ! & ! & ! & ! & ! & nbsp //Dec ECX de noter combien nous avons de gauche a copier
& ! & ! & ! & ! & nbsp & nbsp & nbsp & nbsp Dec ECX
& ! & ! & ! & ! & ! & ! & ! & nbsp //Si ECX <> 0 alors la boucle
& ! & ! & ! & ! & ! & ! & ! & nbsp Jnz @Boucle
& ! & ! & ! & ! & ! & ! & ! & nbsp pop EDI
& ! & ! & ! & ! & ! & ! & nbsp & nbsp pop ESI
& ! & ! & ! & nbsp @JustQuit:
fin
{ TFIFOStream }
fonction de TFIFOStream.BufferReadSize: Integer
begin
& nbsp & nbsp si FBufferEnd >= FBufferStart alors //Pas de boucle
& ! & ! & ! & nbsp Resultat := FBufferEnd - FBufferStart
& nbsp & nbsp else //Boucle
& ! & ! & ! & nbsp Resultat := FMemorySize - FBufferStart FBufferEnd
fin
fonction de TFIFOStream.BufferWriteSize: Integer
begin
& nbsp & nbsp Resultat := FMemorySize - BufferReadSize
fin
procedure TFIFOStream.Clair
begin
& nbsp & nbsp FBufferEnd := 0
& nbsp & nbsp FBufferStart := 0
fin
constructeur TFIFOStream.Creer(aSize: Entier)
begin
& nbsp & nbsp herite de Creer
// si l'aSize < 1024
// raise EFIFOStream.Create('taille de la memoire Tampon doit etre d'au moins 1K.')
& nbsp & nbsp FMemorySize := aSize
& nbsp & nbsp Getmem(FData, FMemorySize)
& nbsp & nbsp FBufferStart := 0
& nbsp & nbsp FBufferEnd := 0
fin
destructeur TFIFOStream.Detruire
begin
& nbsp & nbsp FreeMem(FData)
& nbsp & nbsp herite
fin
procedure TFIFOStream.Peek(const aBuffer: Pointeur Count: Integer)
var
& nbsp & nbsp OrigStart : Integer
begin
& nbsp & nbsp OrigStart := FBufferStart
& nbsp & nbsp essayer
& ! & ! & ! & nbsp Lire(aBuffer, Comte)
& nbsp & nbsp enfin
& ! & ! & ! & nbsp FBufferStart := OrigStart
& nbsp & nbsp fin
fin
procedure TFIFOStream.Lire(const aBuffer : Pointeur Count: Integer)
var
& nbsp & nbsp Source,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Source := @FData[FBufferStart]
& nbsp & nbsp Dest := aBuffer
& nbsp & nbsp si BufferReadSize < Comte
& ! & ! & ! & nbsp elever EFIFOStream.Create('depassement de memoire Tampon.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferStart
& nbsp & nbsp si CopyLen > Comte CopyLen := Count
& nbsp & nbsp CharMove(Source^,B^,CopyLen)
& nbsp & nbsp Inc(FBufferStart,CopyLen)
& nbsp & nbsp //Si la boucle
& nbsp & nbsp si FBufferStart >= FMemorySize puis commencer
& ! & ! & ! & nbsp FBufferStart := FBufferStart - FMemorySize
& ! & ! & ! & nbsp Lire(@Dest[CopyLen],le Comte-CopyLen)
& nbsp & nbsp fin
fin
procedure TFIFOStream.Write(const aSource : Pointeur Count: Integer)
var
& nbsp & nbsp Source,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Source := aSource
& nbsp & nbsp Dest := @FData[FBufferEnd]
& nbsp & nbsp si BufferWriteSize < Comte
& ! & ! & ! & nbsp elever EFIFOStream.Create('Buffer over-run.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferEnd
& nbsp & nbsp si CopyLen > Comte CopyLen := Count
& nbsp & nbsp CharMove(Source^,B^,CopyLen)
& nbsp & nbsp Inc(FBufferEnd,CopyLen)
& nbsp & nbsp //Si la boucle
& nbsp & nbsp si FBufferEnd >= FMemorySize puis commencer
& ! & ! & ! & nbsp FBufferEnd := FBufferEnd - FMemorySize
& ! & ! & ! & nbsp Ecrire(@Source[CopyLen],le Comte-CopyLen)
& nbsp & nbsp fin
fin
a la fin.
Fifo flux
By commentfaire
Fifo flux : Plusieurs milliers de conseils pour vous faciliter la vie.