unit IOBuffer; interface USES Windows, SysUtils, MI1201ioctl; type tBuffer=class private prBuffer:array of byte; prLockMutexHandle:THANDLE; protected procedure SetSize(aSize:cardinal); virtual; function GetSize:cardinal; virtual; function MinimalSize:cardinal; virtual; public constructor Create; overload; constructor Create(aInitialSize:cardinal); overload; destructor Destroy; override; procedure Lock; procedure UnLock; function LockAndGetBufferPtr:pointer; function GetBufferPtr:pointer; property Size:cardinal read GetSize write SetSize; end; tOutBuffer=class(tBuffer) private protected procedure SetSize(aSize:cardinal); override; function GetSize:cardinal; override; procedure SetByte(aIndex:cardinal; aByte:byte); function GetByte(aIndex:cardinal):byte; function MinimalSize:cardinal; override; public function LockAndGetBufferPtr:ptGENPORT_WRITE_MULTI_INPUT_BUFFER; function GetBufferPtr:ptGENPORT_WRITE_MULTI_INPUT_BUFFER; function LockAndGetByteBufferPtr:ptArrayOfByte; function GetByteBufferPtr:ptArrayOfByte; procedure AssignByteArray(const aByteArray:array of byte); overload; procedure AssignByteArray(const aByteArray; aSize:cardinal); overload; property ByteArray[Index:cardinal]:byte read GetByte write SetByte; end; tInBuffer=class(tBuffer) private protected procedure SetSize(aSize:cardinal); override; function GetSize:cardinal; override; procedure SetByte(aIndex:cardinal; aByte:byte); function GetByte(aIndex:cardinal):byte; function MinimalSize:cardinal; override; public function LockAndGetBufferPtr:ptGENPORT_READ_MULTI_OUTPUT_BUFFER; function GetBufferPtr:ptGENPORT_READ_MULTI_OUTPUT_BUFFER; function LockAndGetByteBufferPtr:ptArrayOfByte; function GetByteBufferPtr:ptArrayOfByte; procedure CopyByteArrayTo(var aByteArray:array of byte); overload; procedure CopyByteArrayTo(var aByteArray; aSize:word); overload; property ByteArray[Index:cardinal]:byte read GetByte write SetByte; end; implementation function tInBuffer.MinimalSize:cardinal; begin Result:=SizeOf(tGENPORT_READ_MULTI_OUTPUT_BUFFER); end; function tInBuffer.LockAndGetBufferPtr:ptGENPORT_READ_MULTI_OUTPUT_BUFFER; begin Result:=ptGENPORT_READ_MULTI_OUTPUT_BUFFER(Inherited LockAndGetBufferPtr); end; function tInBuffer.GetBufferPtr:ptGENPORT_READ_MULTI_OUTPUT_BUFFER; begin Result:=ptGENPORT_READ_MULTI_OUTPUT_BUFFER(Inherited GetBufferPtr); end; function tInBuffer.LockAndGetByteBufferPtr:ptArrayOfByte; begin Result:=@LockAndGetBufferPtr^.Data; end; function tInBuffer.GetByteBufferPtr:ptArrayOfByte; begin Result:=@GetBufferPtr^.Data; end; procedure tInBuffer.SetSize(aSize:cardinal); begin if aSize>SizeOf(ULONG) then Inherited SetSize(SizeOf(GetBufferPtr^)+aSize-SizeOf(ULONG)); end; function tInBuffer.GetSize:cardinal; begin Result:=Inherited GetSize-SizeOf(GetBufferPtr^)+SizeOf(ULONG); end; procedure tInBuffer.SetByte(aIndex:cardinal; aByte:byte); begin if aIndex>=Size then begin Size:=aIndex+SizeOf(ULONG); end; GetByteBufferPtr^[aIndex]:=aByte; end; function tInBuffer.GetByte(aIndex:cardinal):byte; begin {$IfOpt R+} if aIndex>=Size then begin raise ERangeError.Create('tInBuffer.GetByte: Invalid aIndex.'); end; {$EndIf Opt R+} Result:=GetByteBufferPtr^[aIndex]; end; procedure tInBuffer.CopyByteArrayTo(var aByteArray:array of byte); begin CopyByteArrayTo(aByteArray[0], Length(aByteArray)); end; procedure tInBuffer.CopyByteArrayTo(var aByteArray; aSize:word); begin {$IfOpt R+} if aSize>Size then begin raise ERangeError.Create('tInBuffer.CopyByteArrayTo: Invalid data size.'); end; {$EndIf Opt R+} Move(GetByteBufferPtr^[0], aByteArray, aSize); end; //------------------------------------------------------- function tOutBuffer.MinimalSize:cardinal; begin Result:=SizeOf(tGENPORT_WRITE_MULTI_INPUT_BUFFER); end; procedure tOutBuffer.SetSize(aSize:cardinal); begin if aSize>SizeOf(ULONG) then Inherited SetSize(SizeOf(GetBufferPtr^)+aSize-SizeOf(ULONG)); end; function tOutBuffer.GetSize:cardinal; begin Result:=Inherited GetSize-SizeOf(GetBufferPtr^)+SizeOf(ULONG); end; function tOutBuffer.LockAndGetBufferPtr:ptGENPORT_WRITE_MULTI_INPUT_BUFFER; begin Result:=ptGENPORT_WRITE_MULTI_INPUT_BUFFER(Inherited LockAndGetBufferPtr); end; function tOutBuffer.GetBufferPtr:ptGENPORT_WRITE_MULTI_INPUT_BUFFER; begin Result:=ptGENPORT_WRITE_MULTI_INPUT_BUFFER(Inherited GetBufferPtr); end; function tOutBuffer.LockAndGetByteBufferPtr:ptArrayOfByte; begin Result:=@LockAndGetBufferPtr^.Data; end; function tOutBuffer.GetByteBufferPtr:ptArrayOfByte; begin Result:=@GetBufferPtr^.Data; end; procedure tOutBuffer.SetByte(aIndex:cardinal; aByte:byte); begin if aIndex>=Size then begin Size:=aIndex+SizeOf(ULONG); end; GetByteBufferPtr^[aIndex]:=aByte; end; function tOutBuffer.GetByte(aIndex:cardinal):byte; begin {$IfOpt R+} if aIndex>=Size then begin raise ERangeError.Create('tOutBuffer.GetByte: Invalid aIndex.'); end; {$EndIf Opt R+} Result:=GetByteBufferPtr^[aIndex]; end; procedure tOutBuffer.AssignByteArray(const aByteArray:array of byte); begin AssignByteArray(aByteArray[0], Length(aByteArray)); end; procedure tOutBuffer.AssignByteArray(const aByteArray; aSize:cardinal); begin if Size0); try SetLength(prBuffer,MinimalSize+aInitialSize) finally ReleaseMutex(prLockMutexHandle); end; end; destructor tBuffer.Destroy; begin Lock; SetLength(prBuffer,0); CloseHandle(prLockMutexHandle); end; function tBuffer.MinimalSize:cardinal; begin Result:=0; end; procedure tBuffer.Lock; begin Win32Check(WAIT_OBJECT_0=WaitForSingleObject(prLockMutexHandle,INFINITE)); end; procedure tBuffer.UnLock; begin Win32Check(ReleaseMutex(prLockMutexHandle)); end; function tBuffer.LockAndGetBufferPtr:pointer; begin Lock; Result:=GetBufferPtr; end; function tBuffer.GetBufferPtr:pointer; begin if Length(prBuffer)>0 then Result:=@prBuffer[0] else Result:=NIL; end; function tBuffer.GetSize:cardinal; begin Result:=Length(prBuffer); end; procedure tBuffer.SetSize(aSize:cardinal); begin Lock; If Size