unit BiDirBuf; {Martin Harvey 7/5/2000} interface uses BoundedBuf; type TBufferSide = (bsSideA, bsSideB); TBufferOp = (boWriting, boReading); TBiDirBuf = class private FAtoBBuf, FBtoABuf: TBoundedBuffer; protected function GetBuf(Side: TBufferSide; Op: TBufferOp): TBoundedBuffer; function GetSize: integer; procedure SetSize(NewSize: integer); public constructor Create; destructor Destroy; override; procedure ResetState; function PutItem(Side: TBufferSide; Item: pointer): boolean; function GetItem(Side: TBufferSide): pointer; { Entries used function peeks buffer one is reading from, and Entried free function peeks buffer one is writing to. It seems a bit useless to allow the other two operations: why worry about your neighbour when you have plenty else to worry about? } function GetEntriesUsed(Side: TBufferSide; var Used: integer): boolean; function GetEntriesFree(Side: TBufferSide; var Free: integer): boolean; published property Size: integer read GetSize write SetSize; end; implementation { TBiDirBuf } constructor TBiDirBuf.Create; begin inherited Create; FAToBBuf := TBoundedBuffer.Create; FBToABuf := TBoundedBuffer.Create; end; destructor TBiDirBuf.Destroy; begin FAToBBuf.Free; FBToABuf.Free; inherited Destroy; end; procedure TBiDirBuf.ResetState; begin FAToBBuf.ResetState; FBToABuf.ResetState; end; function TBiDirBuf.GetBuf(Side: TBufferSide; Op: TBufferOp): TBoundedBuffer; begin if ((Side = bsSideA) and (Op = boWriting)) or ((Side = bsSideB) and (Op = boReading)) then result := FAToBBuf else if ((Side = bsSideA) and (Op = boReading)) or ((Side = bsSideB) and (Op = boWriting)) then result := FBToABuf else begin result := FAToBBuf; Assert(false); end; end; function TBidirBuf.GetSize: integer; begin Assert(FAToBBuf.Size = FBToABuf.Size); result := FAToBBuf.Size; end; procedure TBiDirBuf.SetSize(NewSize: integer); begin FAToBBuf.Size := NewSize; FBToABuf.Size := NewSize; Assert(FAToBBuf.Size = FBToABuf.Size); end; function TBiDirBuf.PutItem(Side: TBufferSide; Item: Pointer): boolean; begin result := GetBuf(Side, boWriting).PutItem(Item); end; function TBiDirBuf.GetItem(Side: TBufferSide): Pointer; begin result := GetBuf(Side, boReading).GetItem; end; function TBiDirBuf.GetEntriesUsed(Side: TBufferSide; var Used: integer): boolean; begin result := GetBuf(Side, boReading).GetEntriesUsed(Used); end; function TBiDirBuf.GetEntriesFree(Side: TBufferSide; var Free: integer): boolean; begin result := GetBuf(Side, boWriting).GetEntriesFree(Free); end; end.