FIFO stream

En Delphi klassen gjennomføring av en FIFO stream.A FIFO stream (First In First Out) er nyttig når du må hele tiden motta data til et medlem buffer, men ønsker ikke at minnebuffer å stadig grow.It brukes vanligvis når du mottar en MP3 audio stream fra Internett. Du må kanskje holde på til en full Mp3 buffer er mottatt, men ikke vil at buffer til å fortsette å vokse til full størrelse på Mp3 være streamed.The Trikset er å gjennomføre en sirkulær buffer, når du skriver forbi utgangen av bufferen posisjon er tilbakestilt til starten av bufferen. Det eneste problemet egentlig som kan skje er at du kan motta data raskere enn du behandle den, noe som resulterer i en buffer overflow. Det er lurt å gjøre buffer for stort i første omgang. Her er min egen gjennomføring. Vennligst ikke fjerne merknaden om opphavsrett < ========== klipp ========= > //(C) Peter Morris - [email protected] /pete @ droopyeyes.. comunit FIFOStream; interfaceuses Windows, Meldinger, SysUtils, Klasser -typen EFIFOStream = klasse (Unntak); TFIFOStream = klasse (TObject) private FData: PChar; FMemorySize: Integer; FBufferEnd, FBufferStart: Integer; beskyttet offentlig konstruktør Opprette (aSize: Integer); virtuell; destructor Destroy; styre; funksjon BufferReadSize: Integer; funksjon BufferWriteSize: Integer; prosedyre Clear; Prosedyren Peek (konst aBuffer: Pointer; Count: Integer); Prosedyren Read (konst aBuffer: Pointer; Count: Integer); Prosedyren Write (konst aSource: Pointer; Count: Integer); publisert enden, implementationprocedure CharMove (konst Kilde; Var Mål, Count: Integer); asm //Merk: Når denne funksjonen kalles, passerer Delphi parametrene som følger //ECX = Count //EAX = Const Kilde //EDX = Div dest //Hvis ingen bytes til å kopiere, bare slutte helt, ikke noe poeng å skyve registre cmp ECX, 0 JeJustQuit //Bevar de kritiske Delphi registrene presse ESI presse EDI //flytte Source inn ESI (vanligvis SOURCE register) //flytte dest inn EDI (vanligvis MÅL registrere for streng kommandoer) //Dette kan faktisk ikke være nødvendig, som jeg ikke bruker MOVsb etc //jeg kan være i stand bare for å bruke EAX og EDX, kan det være en straff for //ikke bruker ESI, EDI men jeg tviler på det, dette er en annen ting verdt å prøve! mov ESI, EAX mov EDI, er EDX //Følgende sløyfe det samme som repNZ MovSB, men merkelig raskere! Loop: //Få kilde byte Mov AL, [ESI] //Point til neste byte Inc ESI //Sett det inn i dest mov [EDI], AL //Point dest til neste posisjon Inc EDI //desember ECX til legg merke til hvor mange vi har igjen å kopiere desember ECX //Hvis ECX < > 0 da sløyfe JNZLoop pop EDI pop ESIJustQuit: end {TFIFOStream} funksjon TFIFOStream.BufferReadSize: Integer; begynne hvis FBufferEnd > = FBufferStart deretter //Ikke loopet Resultat: = FBufferEnd - FBufferStart annet //Looped Resultat: = FMemorySize - FBufferStart + FBufferEnd; ende; funksjon TFIFOStream.BufferWriteSize: Integer; begynne Resultat: = FMemorySize - BufferReadSize; ende; prosedyre TFIFOStream.Clear; begynne FBufferEnd: = 0; FBufferStart: = 0; ende; konstruktør TFIFOStream.Create (aSize: Integer); begynner arvet Opprett; //hvis aSize < 1024 da //heve EFIFOStream.Create ('Buffer størrelse må være minst 1K.'); FMemorySize: = aSize; Getmem (FData, FMemorySize); FBufferStart: = 0; FBufferEnd: = 0; ende; destructor TFIFOStream.Destroy; begynne FreeMem (FData); arvet; ende; prosedyre TFIFOStream.Peek (konst aBuffer: Pointer; Count: Integer); Var OrigStart: Integer; begynne OrigStart: = FBufferStart; prøv Read (aBuffer, Count); endelig FBufferStart: = OrigStart; end, end, prosedyre TFIFOStream.Read (konst aBuffer: Pointer; Count: Integer); Var Source, Mål: PChar; CopyLen: Integer; begynne Kilde: =FData [FBufferStart]; Mål: = aBuffer; hvis BufferReadSize < Telle deretter heve EFIFOStream.Create ('Buffer under-løp.'); CopyLen: = FMemorySize - FBufferStart; hvis CopyLen > Telle så CopyLen: = teller; CharMove (Kilde ^, dest ^, CopyLen); Inc (FBufferStart, CopyLen); //Hvis loopet hvis FBufferStart > = FMemorySize deretter begynne FBufferStart: = FBufferStart - FMemorySize; Les (Dest [CopyLen], Count-CopyLen); end, end, prosedyre TFIFOStream.Write (konst aSource: Pointer; Count: Integer); Var Source, Mål: PChar; CopyLen: Integer; begynne Kilde: = aSource; Mål: =FData [FBufferEnd]; hvis BufferWriteSize < Telle deretter heve EFIFOStream.Create ('Buffer overdrevet.'); CopyLen: = FMemorySize - FBufferEnd; hvis CopyLen > Telle så CopyLen: = teller; CharMove (Kilde ^, dest ^, CopyLen); Inc (FBufferEnd, CopyLen); //Hvis loopet hvis FBufferEnd > = FMemorySize deretter begynne FBufferEnd: = FBufferEnd - FMemorySize; Write (Source [CopyLen], Count-CopyLen); end, end;. slutten Anmeldelser



Previous:
Next Page: