Fifo stream
Una de Delphi de la clase de implementación de un sistema de corriente.
UN flujo FIFO (First In First Out) es útil cuando se necesita que constantemente reciben datos a un miembro de búfer, pero no quiero que la memoria búfer para crecer constantemente.
se utiliza normalmente cuando se recibe un Mp3 streaming de audio desde Internet. Usted puede ser que necesite para aguantar hasta un completo Mp3 buffer ha sido recibido, pero no quiere que su búfer para continuar creciendo, hasta el tamaño total de los archivos Mp3 que se transmite.
El truco es aplicar un buffer circular, una vez que usted escribe más allá del final del búfer de su posición, se restablece el principio del búfer. El único problema que puede ocurrir es que puede recibir los datos más rápido de lo que usted proceso, resultando en un desbordamiento de búfer. Es aconsejable hacer el buffer demasiado grande en el primer lugar. Aquí es mi propia implementación. Por favor, no quite el aviso de derechos de autor.
<==========SNIP=========>
//(C) Peter Morris - [email protected] / [email protected]
unidad de FIFOStream
interfaz
usos
& nbsp & nbsp Windows, Messages, SysUtils, Classes
tipo
& nbsp & nbsp EFIFOStream = clase(Excepción)
& nbsp & nbsp TFIFOStream = class(TObject)
& nbsp & nbsp privada
& nbsp & nbsp & nbsp & nbsp FData : PChar
& nbsp & nbsp & nbsp & nbsp FMemorySize : Integer
& nbsp & nbsp & nbsp & nbsp FBufferEnd,
& nbsp & nbsp & nbsp & nbsp FBufferStart : Integer
& nbsp & nbsp protegido
& nbsp & nbsp pública
& nbsp & nbsp & nbsp & nbsp constructor Create(aSize : Integer) virtual
& nbsp & nbsp & nbsp & nbsp destructor Destruir reemplazar
& nbsp & nbsp & nbsp & nbsp función BufferReadSize : Integer
& nbsp & nbsp & nbsp & nbsp función BufferWriteSize : Integer
& nbsp & nbsp & nbsp & nbsp procedimiento Claro
& nbsp & nbsp & nbsp & nbsp procedimiento Peek(const aBuffer : Recuento de Puntero : Integer)
& nbsp & nbsp & nbsp & nbsp procedimiento de Lectura(const aBuffer : Recuento de Puntero : Integer)
& nbsp & nbsp & nbsp & nbsp procedimiento Write(const aSource : Recuento de Puntero : Integer)
& nbsp & nbsp publicado
& nbsp & nbsp final
aplicación
procedimiento CharMove(const Fuente var Dest Cantidad : Integer)
asm
//Nota: Cuando se llama a esta función, delphi pasa los parámetros de la siguiente manera
//ECX = Count
//EAX = Const Fuente
//EDX = Var Dest
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Si no hay bytes a copiar, acaba de salir del todo, no hay punto de empujar a los registros
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cmp ECX,0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Je @JustQuit
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Preservar la crítica delphi registros
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp push ESI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp push EDI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Origen del movimiento en ESI (generalmente la FUENTE de registro)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //mover Dest en EDI (generalmente el DESTINO de registro de cadena de comandos)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Esta realidad no puede ser necesario, como no soy de usar MOVsb etc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //que puede ser capaz de usar simplemente el EAX y EDX, puede haber una sanción para
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //no uso de ESI, EDI, pero lo dudo, esta es otra cosa que vale la pena probar !
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mov ESI, EAX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mov EDI, intercambio de datos electrónicos
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //El siguiente ciclo es el mismo que repNZ MovSB, pero curiosamente más rápido !
& nbsp & nbsp & nbsp & nbsp @Bucle:
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Obtener el código de bytes
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Mov AL, [ESI]
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Punto a la siguiente byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc ESI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Poner en el Dest
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mov [EDI], AL
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Punto de destino a la posición siguiente
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc EDI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Dec ECX notar que muchos hemos dejado para copiar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Dec ECX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Si ECX <> 0 entonces bucle
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Jnz @Loop
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp pop EDI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp pop ESI
& nbsp & nbsp & nbsp & nbsp @JustQuit:
fin
{ TFIFOStream }
función TFIFOStream.BufferReadSize: Integer
begin
& nbsp & nbsp si FBufferEnd >= FBufferStart entonces //No en bucle
& nbsp & nbsp & nbsp & nbsp Resultado := FBufferEnd - FBufferStart
& nbsp & nbsp else //Bucle
& nbsp & nbsp & nbsp & nbsp Resultado := FMemorySize - FBufferStart FBufferEnd
fin
función TFIFOStream.BufferWriteSize: Integer
begin
& nbsp & nbsp Resultado := FMemorySize - BufferReadSize
fin
procedimiento TFIFOStream.Claro
begin
& nbsp & nbsp FBufferEnd := 0
& nbsp & nbsp FBufferStart := 0
fin
constructor TFIFOStream.Crear(aSize: Integer)
begin
& nbsp & nbsp heredado Crear
// si aSize < 1024, a continuación,
// subir EFIFOStream.Create('Buffer de tamaño debe ser al menos de 1K.')
& nbsp & nbsp FMemorySize := aSize
& nbsp & nbsp Getmem(FData, FMemorySize)
& nbsp & nbsp FBufferStart := 0
& nbsp & nbsp FBufferEnd := 0
fin
destructor TFIFOStream.Destruir
begin
& nbsp & nbsp FreeMem(FData)
& nbsp & nbsp heredado
fin
procedimiento TFIFOStream.Peek(const aBuffer: Recuento de Puntero: Integer)
var
& nbsp & nbsp OrigStart : Integer
begin
& nbsp & nbsp OrigStart := FBufferStart
& nbsp & nbsp probar
& nbsp & nbsp & nbsp & nbsp Leer(aBuffer, Count)
& nbsp & nbsp finalmente
& nbsp & nbsp & nbsp & nbsp FBufferStart := OrigStart
& nbsp & nbsp final
fin
procedimiento TFIFOStream.Leer(const aBuffer : Recuento de Puntero: Integer)
var
& nbsp & nbsp Fuente,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Fuente := @FData[FBufferStart]
& nbsp & nbsp Dest := aBuffer
& nbsp & nbsp si BufferReadSize < Count, a continuación,
& nbsp & nbsp & nbsp & nbsp elevar EFIFOStream.Create('Buffer bajo-ejecutar.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferStart
& nbsp & nbsp si CopyLen > Número, a continuación, CopyLen := Count
& nbsp & nbsp CharMove(Fuente^,Dest^,CopyLen)
& nbsp & nbsp Inc(FBufferStart,CopyLen)
& nbsp & nbsp //Si el bucle
& nbsp & nbsp si FBufferStart >= FMemorySize, a continuación, empezar
& nbsp & nbsp & nbsp & nbsp FBufferStart := FBufferStart - FMemorySize
& nbsp & nbsp & nbsp & nbsp Leer(@Dest[CopyLen],Conde-CopyLen)
& nbsp & nbsp final
fin
procedimiento TFIFOStream.Escribir(const aSource : Recuento de Puntero: Integer)
var
& nbsp & nbsp Fuente,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Fuente := aSource
& nbsp & nbsp Dest := @FData[FBufferEnd]
& nbsp & nbsp si BufferWriteSize < Count, a continuación,
& nbsp & nbsp & nbsp & nbsp elevar EFIFOStream.Create('Buffer de ejecución.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferEnd
& nbsp & nbsp si CopyLen > Número, a continuación, CopyLen := Count
& nbsp & nbsp CharMove(Fuente^,Dest^,CopyLen)
& nbsp & nbsp Inc(FBufferEnd,CopyLen)
& nbsp & nbsp //Si el bucle
& nbsp & nbsp si FBufferEnd >= FMemorySize, a continuación, empezar
& nbsp & nbsp & nbsp & nbsp FBufferEnd := FBufferEnd - FMemorySize
& nbsp & nbsp & nbsp & nbsp Escribir(@Fuente[CopyLen],Conde-CopyLen)
& nbsp & nbsp final
fin
final.
Fifo stream
Fifo stream : Multi-millones de consejos para hacer su vida mas facil.
Una de Delphi de la clase de implementacion de un sistema de corriente.
UN flujo FIFO (First In First Out) es util cuando se necesita que constantemente reciben datos a un miembro de bufer, pero no quiero que la memoria bufer para crecer constantemente.
se utiliza normalmente cuando se recibe un Mp3 streaming de audio desde Internet. Usted puede ser que necesite para aguantar hasta un completo Mp3 buffer ha sido recibido, pero no quiere que su bufer para continuar creciendo, hasta el tamaño total de los archivos Mp3 que se transmite.
El truco es aplicar un buffer circular, una vez que usted escribe mas alla del final del bufer de su posicion, se restablece el principio del bufer. El unico problema que puede ocurrir es que puede recibir los datos mas rapido de lo que usted proceso, resultando en un desbordamiento de bufer. Es aconsejable hacer el buffer demasiado grande en el primer lugar. Aqui es mi propia implementacion. Por favor, no quite el aviso de derechos de autor.
<==========SNIP=========>
//(C) Peter Morris - [email protected] / [email protected]
unidad de FIFOStream
interfaz
usos
& nbsp & nbsp Windows, Messages, SysUtils, Classes
tipo
& nbsp & nbsp EFIFOStream = clase(Excepcion)
& nbsp & nbsp TFIFOStream = class(TObject)
& nbsp & nbsp privada
& nbsp & nbsp & nbsp & nbsp FData : PChar
& nbsp & nbsp & nbsp & nbsp FMemorySize : Integer
& nbsp & nbsp & nbsp & nbsp FBufferEnd,
& nbsp & nbsp & nbsp & nbsp FBufferStart : Integer
& nbsp & nbsp protegido
& nbsp & nbsp publica
& nbsp & nbsp & nbsp & nbsp constructor Create(aSize : Integer) virtual
& nbsp & nbsp & nbsp & nbsp destructor Destruir reemplazar
& nbsp & nbsp & nbsp & nbsp funcion BufferReadSize : Integer
& nbsp & nbsp & nbsp & nbsp funcion BufferWriteSize : Integer
& nbsp & nbsp & nbsp & nbsp procedimiento Claro
& nbsp & nbsp & nbsp & nbsp procedimiento Peek(const aBuffer : Recuento de Puntero : Integer)
& nbsp & nbsp & nbsp & nbsp procedimiento de Lectura(const aBuffer : Recuento de Puntero : Integer)
& nbsp & nbsp & nbsp & nbsp procedimiento Write(const aSource : Recuento de Puntero : Integer)
& nbsp & nbsp publicado
& nbsp & nbsp final
aplicacion
procedimiento CharMove(const Fuente var Dest Cantidad : Integer)
asm
//Nota: Cuando se llama a esta funcion, delphi pasa los parametros de la siguiente manera
//ECX = Count
//EAX = Const Fuente
//EDX = Var Dest
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Si no hay bytes a copiar, acaba de salir del todo, no hay punto de empujar a los registros
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp cmp ECX,0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Je @JustQuit
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Preservar la critica delphi registros
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp push ESI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp push EDI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Origen del movimiento en ESI (generalmente la FUENTE de registro)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //mover Dest en EDI (generalmente el DESTINO de registro de cadena de comandos)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Esta realidad no puede ser necesario, como no soy de usar MOVsb etc
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //que puede ser capaz de usar simplemente el EAX y EDX, puede haber una sancion para
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //no uso de ESI, EDI, pero lo dudo, esta es otra cosa que vale la pena probar !
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mov ESI, EAX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mov EDI, intercambio de datos electronicos
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //El siguiente ciclo es el mismo que repNZ MovSB, pero curiosamente mas rapido !
& nbsp & nbsp & nbsp & nbsp @Bucle:
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Obtener el codigo de bytes
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Mov AL, [ESI]
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Punto a la siguiente byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc ESI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Poner en el Dest
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp mov [EDI], AL
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Punto de destino a la posicion siguiente
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc EDI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Dec ECX notar que muchos hemos dejado para copiar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Dec ECX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //Si ECX <> 0 entonces bucle
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Jnz @Loop
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp pop EDI
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp pop ESI
& nbsp & nbsp & nbsp & nbsp @JustQuit:
fin
{ TFIFOStream }
funcion TFIFOStream.BufferReadSize: Integer
begin
& nbsp & nbsp si FBufferEnd >= FBufferStart entonces //No en bucle
& nbsp & nbsp & nbsp & nbsp Resultado := FBufferEnd - FBufferStart
& nbsp & nbsp else //Bucle
& nbsp & nbsp & nbsp & nbsp Resultado := FMemorySize - FBufferStart FBufferEnd
fin
funcion TFIFOStream.BufferWriteSize: Integer
begin
& nbsp & nbsp Resultado := FMemorySize - BufferReadSize
fin
procedimiento TFIFOStream.Claro
begin
& nbsp & nbsp FBufferEnd := 0
& nbsp & nbsp FBufferStart := 0
fin
constructor TFIFOStream.Crear(aSize: Integer)
begin
& nbsp & nbsp heredado Crear
// si aSize < 1024, a continuacion,
// subir EFIFOStream.Create('Buffer de tamaño debe ser al menos de 1K.')
& nbsp & nbsp FMemorySize := aSize
& nbsp & nbsp Getmem(FData, FMemorySize)
& nbsp & nbsp FBufferStart := 0
& nbsp & nbsp FBufferEnd := 0
fin
destructor TFIFOStream.Destruir
begin
& nbsp & nbsp FreeMem(FData)
& nbsp & nbsp heredado
fin
procedimiento TFIFOStream.Peek(const aBuffer: Recuento de Puntero: Integer)
var
& nbsp & nbsp OrigStart : Integer
begin
& nbsp & nbsp OrigStart := FBufferStart
& nbsp & nbsp probar
& nbsp & nbsp & nbsp & nbsp Leer(aBuffer, Count)
& nbsp & nbsp finalmente
& nbsp & nbsp & nbsp & nbsp FBufferStart := OrigStart
& nbsp & nbsp final
fin
procedimiento TFIFOStream.Leer(const aBuffer : Recuento de Puntero: Integer)
var
& nbsp & nbsp Fuente,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Fuente := @FData[FBufferStart]
& nbsp & nbsp Dest := aBuffer
& nbsp & nbsp si BufferReadSize < Count, a continuacion,
& nbsp & nbsp & nbsp & nbsp elevar EFIFOStream.Create('Buffer bajo-ejecutar.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferStart
& nbsp & nbsp si CopyLen > Numero, a continuacion, CopyLen := Count
& nbsp & nbsp CharMove(Fuente^,Dest^,CopyLen)
& nbsp & nbsp Inc(FBufferStart,CopyLen)
& nbsp & nbsp //Si el bucle
& nbsp & nbsp si FBufferStart >= FMemorySize, a continuacion, empezar
& nbsp & nbsp & nbsp & nbsp FBufferStart := FBufferStart - FMemorySize
& nbsp & nbsp & nbsp & nbsp Leer(@Dest[CopyLen],Conde-CopyLen)
& nbsp & nbsp final
fin
procedimiento TFIFOStream.Escribir(const aSource : Recuento de Puntero: Integer)
var
& nbsp & nbsp Fuente,
& nbsp & nbsp Dest : PChar
& nbsp & nbsp CopyLen : Integer
begin
& nbsp & nbsp Fuente := aSource
& nbsp & nbsp Dest := @FData[FBufferEnd]
& nbsp & nbsp si BufferWriteSize < Count, a continuacion,
& nbsp & nbsp & nbsp & nbsp elevar EFIFOStream.Create('Buffer de ejecucion.')
& nbsp & nbsp CopyLen := FMemorySize - FBufferEnd
& nbsp & nbsp si CopyLen > Numero, a continuacion, CopyLen := Count
& nbsp & nbsp CharMove(Fuente^,Dest^,CopyLen)
& nbsp & nbsp Inc(FBufferEnd,CopyLen)
& nbsp & nbsp //Si el bucle
& nbsp & nbsp si FBufferEnd >= FMemorySize, a continuacion, empezar
& nbsp & nbsp & nbsp & nbsp FBufferEnd := FBufferEnd - FMemorySize
& nbsp & nbsp & nbsp & nbsp Escribir(@Fuente[CopyLen],Conde-CopyLen)
& nbsp & nbsp final
fin
final.
Fifo stream
By Consejos Y Trucos
Fifo stream : Multi-millones de consejos para hacer su vida más fácil.