Una clase Delphi aplicación de un flujo de FIFO.
Un flujo FIFO (First En First Out) es útil cuando se necesita recibir constantemente los datos a un miembro de amortiguación, pero no quieren que la memoria buffer a crecer constantemente.
Se utiliza normalmente cuando se recibe un flujo de audio Mp3 de la Internet. Es posible que tenga que celebrar hasta un total de amortiguación Mp3 se ha recibido, pero no quiere que su buffer para seguir creciendo al tamaño completo de la secuencia de Mp3 ser.
El truco es aplicar un buffer circular, una vez que escribir el pasado fin de la amortiguación de su posición se restablece al comienzo del buffer. El único problema que realmente puede ocurrir es que puede recibir datos más rápido que usted proceso, resultando en un desbordamiento de búfer. Es aconsejable hacer el buffer es demasiado grande, en primer lugar. Aquí está mi propia aplicación. Por favor, no retire el aviso de copyright.
<========== SNIP =========>
/ / (C) Peter Morris - pete@stuckindoors.com / pete@droopyeyes.com
FIFOStream unidad;
interfaz
usos
Windows, Messages, SysUtils, clases;
tipo
EFIFOStream = class (Exception);
TFIFOStream = class (TObject)
privado
FData: PChar;
FMemorySize: Integer;
FBufferEnd,
FBufferStart: Integer;
protegidas
público
constructor Crear (aSize: Integer); virtual;
destructor Destroy; override;
BufferReadSize función: Integer;
BufferWriteSize función: Integer;
procedimiento abierto;
procedimiento Peek (const aBuffer: Pointer; Cuenta: Integer);
Leer procedimiento (const aBuffer: Pointer; Cuenta: Integer);
Escriba procedimiento (const aSource: Pointer; Cuenta: Integer);
publicado
final;
aplicación
procedimiento CharMove (const Fuente; var Dest; Cuenta: Integer);
asm
/ / Nota: Cuando esta función se llama, Delphi pasa de los parámetros de la siguiente manera
/ / ECX = Conde
/ / EAX = Const Fuente
/ / EDX = Var Dest
/ / Si no bytes a copiar, simplemente dejar por completo, no empujar punto registros
cmp ECX, 0
Je @ JustQuit
/ / Preservación de la crítica de Delphi registros
Pulsar ESI
Pulsar EDI
/ / Fuente avanzar en ESI (en general, el registro FUENTE)
/ / mover Dest en EDI (en general, el registro DEST cadena de comandos)
/ / Esto puede no ser realmente necesario, como no estoy utilizando MOVSB etc
/ / I pueden ser capaces de usar sólo EAX y EDX, puede haber una sanción por
/ / no usar ESI, EDI, pero lo dudo, esto es otra cosa vale la pena intentarlo!
mov ESI, EAX
mov EDI, EDX
/ / El siguiente bucle es el mismo que repNZ MOVSB, pero extrañamente rápido!
@ Loop:
/ / Obtener la fuente byte
Mov AL, [ESI]
/ / Apunta a la siguiente byte
ESI Inc
/ / Pon en el Dest
mov [EDI], AL
/ / Punto de destino a la próxima posición
EDI Inc
/ / Dec ECX tomar nota de cuántos hemos dejado de copiar
Diciembre ECX
/ / Si ECX <> 0 then bucle
Jnz @ bucle
Pop EDI
Pop ESI
@ JustQuit:
final;
() TFIFOStream
TFIFOStream.BufferReadSize función: Integer;
empezar
si FBufferEnd> = FBufferStart then / / No bucle
Result: = FBufferEnd - FBufferStart
else / / bucle
Result: = FMemorySize - FBufferStart + FBufferEnd;
final;
TFIFOStream.BufferWriteSize función: Integer;
empezar
Result: = FMemorySize - BufferReadSize;
final;
TFIFOStream.Clear procedimiento;
empezar
FBufferEnd: = 0;
FBufferStart: = 0;
final;
TFIFOStream.Create constructor (aSize: Integer);
empezar
Crear heredado;
/ / Si aSize <1024 entonces
/ / Plantear EFIFOStream.Create ( 'Tamaño de búfer debe ser al menos de 1K.');
FMemorySize: = aSize;
Getmem (FData, FMemorySize);
FBufferStart: = 0;
FBufferEnd: = 0;
final;
TFIFOStream.Destroy destructor;
empezar
FreeMem (FData);
heredado;
final;
procedimiento TFIFOStream.Peek (const aBuffer: Pointer; Cuenta: Integer);
var
OrigStart: Integer;
empezar
OrigStart: = FBufferStart;
intentar
Leer (aBuffer, el conde);
finalmente
FBufferStart: = OrigStart;
final;
final;
procedimiento TFIFOStream.Read (const aBuffer: Pointer; Cuenta: Integer);
var
Fuente,
Dest: PChar;
CopyLen: Integer;
empezar
Fuente: = @ FData [FBufferStart];
Dest: = aBuffer;
si BufferReadSize <entonces Conde
aumentar EFIFOStream.Create ( 'Buffer en virtud de plazo.');
CopyLen: = FMemorySize - FBufferStart;
si CopyLen> Conde CopyLen entonces: = Count;
CharMove (Fuente ^, ^ Dest, CopyLen);
Inc (FBufferStart, CopyLen);
/ / Si bucle
si FBufferStart> = FMemorySize then begin
FBufferStart: = FBufferStart - FMemorySize;
Leer (@ Dest [CopyLen], el conde-CopyLen);
final;
final;
procedimiento TFIFOStream.Write (const aSource: Pointer; Cuenta: Integer);
var
Fuente,
Dest: PChar;
CopyLen: Integer;
empezar
Fuente: = aSource;
Dest: = @ FData [FBufferEnd];
si BufferWriteSize <entonces Conde
aumentar EFIFOStream.Create ( 'Buffer más de plazo.');
CopyLen: = FMemorySize - FBufferEnd;
si CopyLen> Conde CopyLen entonces: = Count;
CharMove (Fuente ^, ^ Dest, CopyLen);
Inc (FBufferEnd, CopyLen);
/ / Si bucle
si FBufferEnd> = FMemorySize then begin
FBufferEnd: = FBufferEnd - FMemorySize;
Escribir (@ Fuente [CopyLen], el conde-CopyLen);
final;
final;
final.
By Peter Morris

Delicious
Digg
Google
Yahoo